mirror of
https://github.com/opencv/opencv.git
synced 2026-07-30 15:53:03 +04:00
Merge pull request #29389 from Prasadayus:cvtcolor_refactor
Refactoring and optimizing cvtcolor in Imgproc #29389 **Key Changes:** 1. Unified three divergent SIMD swap implementations into a single shared `v_swap` helper. 2. Consolidated the repeated `CV_8U/CV_16U/CV_32F` depth-dispatch chains into a single `CvtColorLoopDepth` template. 3. Extracted the duplicated coefficient-selection loops in the YCrCb/YUV constructors into `selectYuvCoeffs`. 4. Collapsed the shared YUV420 store logic duplicated across both decode invokers into `storeYUV420block`. 5. Generalized the inline blue-channel coefficient swaps in `color_lab.cpp` into `swapBlueCoeffsCols`/`swapBlueCoeffsRows`. 6. Added a `v_dotprod`-based SIMD path (`v_RGB2Y`/`v_RGB2UV`) for the previously scalar `RGB8toYUV422Invoker`. 7. Migrated all inline `CV_IPP_CHECK` cvtColor paths out of the dispatch files and into the IPP HAL plugin (`hal/ipp/src/color_ipp.cpp`), replacing each call site with `CALL_HAL`. **Performance Numbers on Intel(R) Core(TM) i9-11900K**: https://docs.google.com/spreadsheets/d/1pz0aHlTeG4Ao8RT7LipgdNSjhCJz92QfZG3GmNa63hU/edit?usp=sharing ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [x] The PR is proposed to the proper branch - [x] There is a reference to the original bug report and related work - [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [x] The feature is well documented and sample code can be built with the project CMake
This commit is contained in:
committed by
GitHub
parent
db37d38eb4
commit
ae93a81ec0
@@ -13,6 +13,7 @@ add_library(ipphal STATIC
|
||||
"${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/color_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"
|
||||
|
||||
@@ -39,4 +39,88 @@ int ipp_hal_remap32f(int src_type, const uchar *src_data, size_t src_step, int s
|
||||
|
||||
#endif //IPP_VERSION_X100 >= 810
|
||||
|
||||
#if IPP_VERSION_X100 >= 700
|
||||
|
||||
#define IPP_DISABLE_YUV_RGB 1 // accuracy difference
|
||||
#define IPP_DISABLE_RGB_YUV 1 // breaks OCL accuracy tests
|
||||
#define IPP_DISABLE_RGB_HSV 1 // breaks OCL accuracy tests
|
||||
#define IPP_DISABLE_RGB_LAB 1 // breaks OCL accuracy tests
|
||||
#define IPP_DISABLE_LAB_RGB 1 // breaks OCL accuracy tests
|
||||
#define IPP_DISABLE_RGB_XYZ 1 // big accuracy difference
|
||||
#define IPP_DISABLE_XYZ_RGB 1 // big accuracy difference
|
||||
|
||||
int ipp_hal_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);
|
||||
#undef cv_hal_cvtBGRtoGray
|
||||
#define cv_hal_cvtBGRtoGray ipp_hal_cvtBGRtoGray
|
||||
|
||||
int ipp_hal_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);
|
||||
#undef cv_hal_cvtBGRtoBGR
|
||||
#define cv_hal_cvtBGRtoBGR ipp_hal_cvtBGRtoBGR
|
||||
|
||||
int ipp_hal_cvtGraytoBGR(const uchar * src_data, size_t src_step, uchar * dst_data, size_t dst_step,
|
||||
int width, int height, int depth, int dcn);
|
||||
#undef cv_hal_cvtGraytoBGR
|
||||
#define cv_hal_cvtGraytoBGR ipp_hal_cvtGraytoBGR
|
||||
|
||||
int ipp_hal_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);
|
||||
#undef cv_hal_cvtBGRtoHSV
|
||||
#define cv_hal_cvtBGRtoHSV ipp_hal_cvtBGRtoHSV
|
||||
|
||||
int ipp_hal_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);
|
||||
#undef cv_hal_cvtHSVtoBGR
|
||||
#define cv_hal_cvtHSVtoBGR ipp_hal_cvtHSVtoBGR
|
||||
|
||||
int ipp_hal_cvtRGBAtoMultipliedRGBA(const uchar * src_data, size_t src_step, uchar * dst_data, size_t dst_step,
|
||||
int width, int height);
|
||||
#undef cv_hal_cvtRGBAtoMultipliedRGBA
|
||||
#define cv_hal_cvtRGBAtoMultipliedRGBA ipp_hal_cvtRGBAtoMultipliedRGBA
|
||||
|
||||
#if !IPP_DISABLE_RGB_YUV
|
||||
int ipp_hal_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);
|
||||
#undef cv_hal_cvtBGRtoYUV
|
||||
#define cv_hal_cvtBGRtoYUV ipp_hal_cvtBGRtoYUV
|
||||
#endif // !IPP_DISABLE_RGB_YUV
|
||||
|
||||
#if !IPP_DISABLE_YUV_RGB
|
||||
int ipp_hal_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);
|
||||
#undef cv_hal_cvtYUVtoBGR
|
||||
#define cv_hal_cvtYUVtoBGR ipp_hal_cvtYUVtoBGR
|
||||
#endif // !IPP_DISABLE_YUV_RGB
|
||||
|
||||
#if !IPP_DISABLE_RGB_XYZ
|
||||
int ipp_hal_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);
|
||||
#undef cv_hal_cvtBGRtoXYZ
|
||||
#define cv_hal_cvtBGRtoXYZ ipp_hal_cvtBGRtoXYZ
|
||||
#endif // !IPP_DISABLE_RGB_XYZ
|
||||
|
||||
#if !IPP_DISABLE_XYZ_RGB
|
||||
int ipp_hal_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);
|
||||
#undef cv_hal_cvtXYZtoBGR
|
||||
#define cv_hal_cvtXYZtoBGR ipp_hal_cvtXYZtoBGR
|
||||
#endif // !IPP_DISABLE_XYZ_RGB
|
||||
|
||||
#if !IPP_DISABLE_RGB_LAB
|
||||
int ipp_hal_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);
|
||||
#undef cv_hal_cvtBGRtoLab
|
||||
#define cv_hal_cvtBGRtoLab ipp_hal_cvtBGRtoLab
|
||||
#endif // !IPP_DISABLE_RGB_LAB
|
||||
|
||||
#if !IPP_DISABLE_LAB_RGB
|
||||
int ipp_hal_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);
|
||||
#undef cv_hal_cvtLabtoBGR
|
||||
#define cv_hal_cvtLabtoBGR ipp_hal_cvtLabtoBGR
|
||||
#endif // !IPP_DISABLE_LAB_RGB
|
||||
|
||||
#endif //IPP_VERSION_X100 >= 700
|
||||
|
||||
#endif //__IPP_HAL_IMGPROC_HPP__
|
||||
|
||||
@@ -0,0 +1,942 @@
|
||||
// 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"
|
||||
#include <opencv2/core.hpp>
|
||||
#include "precomp_ipp.hpp"
|
||||
|
||||
#include <limits>
|
||||
|
||||
#if IPP_VERSION_X100 >= 700
|
||||
|
||||
#define MAX_IPP8u 255
|
||||
#define MAX_IPP16u 65535
|
||||
#define MAX_IPP32f 1.0
|
||||
|
||||
#define IPP_DISABLE_CVTCOLOR_GRAY2BGR_8UC3 1
|
||||
|
||||
namespace {
|
||||
|
||||
typedef IppStatus (CV_STDCALL* ippiGeneralFunc)(const void *, int, void *, int, IppiSize);
|
||||
typedef IppStatus (CV_STDCALL* ippiColor2GrayFunc)(const void *, int, void *, int, IppiSize, const Ipp32f *);
|
||||
typedef IppStatus (CV_STDCALL* ippiReorderFunc)(const void *, int, void *, int, IppiSize, const int *);
|
||||
|
||||
// BT.601 BGR->Y weights
|
||||
static const float B2YF = 0.114f;
|
||||
static const float G2YF = 0.587f;
|
||||
static const float R2YF = 0.299f;
|
||||
|
||||
template<typename _Tp> struct ColorChannel
|
||||
{
|
||||
static inline _Tp max() { return std::numeric_limits<_Tp>::max(); }
|
||||
};
|
||||
template<> struct ColorChannel<float>
|
||||
{
|
||||
static inline float max() { return 1.f; }
|
||||
};
|
||||
|
||||
template <typename Cvt>
|
||||
class CvtColorIPPLoop_Invoker : public cv::ParallelLoopBody
|
||||
{
|
||||
public:
|
||||
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 cv::Range& range) const CV_OVERRIDE
|
||||
{
|
||||
const void *yS = src_data + src_step * range.start;
|
||||
void *yD = dst_data + dst_step * range.start;
|
||||
if( !cvt(yS, static_cast<int>(src_step), yD, static_cast<int>(dst_step), width, range.end - range.start) )
|
||||
*ok = false;
|
||||
else
|
||||
{
|
||||
CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
const uchar * src_data;
|
||||
const size_t src_step;
|
||||
uchar * dst_data;
|
||||
const size_t dst_step;
|
||||
const int width;
|
||||
const Cvt& cvt;
|
||||
bool *ok;
|
||||
|
||||
const CvtColorIPPLoop_Invoker& operator= (const CvtColorIPPLoop_Invoker&);
|
||||
};
|
||||
|
||||
template <typename 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;
|
||||
cv::parallel_for_(cv::Range(0, height),
|
||||
CvtColorIPPLoop_Invoker<Cvt>(src_data, src_step, dst_data, dst_step, width, cvt, &ok),
|
||||
(width * height)/(double)(1<<16) );
|
||||
return ok;
|
||||
}
|
||||
|
||||
template <typename 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)
|
||||
{
|
||||
cv::Mat temp;
|
||||
cv::Mat src(cv::Size(width, height), src_type, const_cast<uchar*>(src_data), src_step);
|
||||
cv::Mat source = src;
|
||||
if( src_data == dst_data )
|
||||
{
|
||||
src.copyTo(temp);
|
||||
source = temp;
|
||||
}
|
||||
bool ok;
|
||||
cv::parallel_for_(cv::Range(0, source.rows),
|
||||
CvtColorIPPLoop_Invoker<Cvt>(source.data, source.step, dst_data, dst_step,
|
||||
source.cols, cvt, &ok),
|
||||
source.total()/(double)(1<<16) );
|
||||
return ok;
|
||||
}
|
||||
|
||||
struct IPPGeneralFunctor
|
||||
{
|
||||
IPPGeneralFunctor(ippiGeneralFunc _func) : ippiColorConvertGeneral(_func){}
|
||||
bool operator()(const void *src, int srcStep, void *dst, int dstStep, int cols, int rows) const
|
||||
{
|
||||
return ippiColorConvertGeneral ? CV_INSTRUMENT_FUN_IPP(ippiColorConvertGeneral, src, srcStep, dst, dstStep, ippiSize(cols, rows)) >= 0 : false;
|
||||
}
|
||||
private:
|
||||
ippiGeneralFunc ippiColorConvertGeneral;
|
||||
};
|
||||
|
||||
struct IPPReorderFunctor
|
||||
{
|
||||
IPPReorderFunctor(ippiReorderFunc _func, int _order0, int _order1, int _order2) : ippiColorConvertReorder(_func)
|
||||
{
|
||||
order[0] = _order0;
|
||||
order[1] = _order1;
|
||||
order[2] = _order2;
|
||||
order[3] = 3;
|
||||
}
|
||||
bool operator()(const void *src, int srcStep, void *dst, int dstStep, int cols, int rows) const
|
||||
{
|
||||
return ippiColorConvertReorder ? CV_INSTRUMENT_FUN_IPP(ippiColorConvertReorder, src, srcStep, dst, dstStep, ippiSize(cols, rows), order) >= 0 : false;
|
||||
}
|
||||
private:
|
||||
ippiReorderFunc ippiColorConvertReorder;
|
||||
int order[4];
|
||||
};
|
||||
|
||||
struct IPPReorderGeneralFunctor
|
||||
{
|
||||
IPPReorderGeneralFunctor(ippiReorderFunc _func1, ippiGeneralFunc _func2, int _order0, int _order1, int _order2, int _depth) :
|
||||
ippiColorConvertReorder(_func1), ippiColorConvertGeneral(_func2), depth(_depth)
|
||||
{
|
||||
order[0] = _order0;
|
||||
order[1] = _order1;
|
||||
order[2] = _order2;
|
||||
order[3] = 3;
|
||||
}
|
||||
bool operator()(const void *src, int srcStep, void *dst, int dstStep, int cols, int rows) const
|
||||
{
|
||||
if (ippiColorConvertReorder == 0 || ippiColorConvertGeneral == 0)
|
||||
return false;
|
||||
|
||||
cv::Mat temp;
|
||||
temp.create(rows, cols, CV_MAKETYPE(depth, 3));
|
||||
if(CV_INSTRUMENT_FUN_IPP(ippiColorConvertReorder, src, srcStep, temp.ptr(), (int)temp.step[0], ippiSize(cols, rows), order) < 0)
|
||||
return false;
|
||||
return CV_INSTRUMENT_FUN_IPP(ippiColorConvertGeneral, temp.ptr(), (int)temp.step[0], dst, dstStep, ippiSize(cols, rows)) >= 0;
|
||||
}
|
||||
private:
|
||||
ippiReorderFunc ippiColorConvertReorder;
|
||||
ippiGeneralFunc ippiColorConvertGeneral;
|
||||
int order[4];
|
||||
int depth;
|
||||
};
|
||||
|
||||
struct IPPGeneralReorderFunctor
|
||||
{
|
||||
IPPGeneralReorderFunctor(ippiGeneralFunc _func1, ippiReorderFunc _func2, int _order0, int _order1, int _order2, int _depth) :
|
||||
ippiColorConvertGeneral(_func1), ippiColorConvertReorder(_func2), depth(_depth)
|
||||
{
|
||||
order[0] = _order0;
|
||||
order[1] = _order1;
|
||||
order[2] = _order2;
|
||||
order[3] = 3;
|
||||
}
|
||||
bool operator()(const void *src, int srcStep, void *dst, int dstStep, int cols, int rows) const
|
||||
{
|
||||
if (ippiColorConvertGeneral == 0 || ippiColorConvertReorder == 0)
|
||||
return false;
|
||||
|
||||
cv::Mat temp;
|
||||
temp.create(rows, cols, CV_MAKETYPE(depth, 3));
|
||||
if(CV_INSTRUMENT_FUN_IPP(ippiColorConvertGeneral, src, srcStep, temp.ptr(), (int)temp.step[0], ippiSize(cols, rows)) < 0)
|
||||
return false;
|
||||
return CV_INSTRUMENT_FUN_IPP(ippiColorConvertReorder, temp.ptr(), (int)temp.step[0], dst, dstStep, ippiSize(cols, rows), order) >= 0;
|
||||
}
|
||||
private:
|
||||
ippiGeneralFunc ippiColorConvertGeneral;
|
||||
ippiReorderFunc ippiColorConvertReorder;
|
||||
int order[4];
|
||||
int depth;
|
||||
};
|
||||
|
||||
struct IPPColor2GrayFunctor
|
||||
{
|
||||
IPPColor2GrayFunctor(ippiColor2GrayFunc _func) : ippiColorToGray(_func)
|
||||
{
|
||||
coeffs[0] = B2YF;
|
||||
coeffs[1] = G2YF;
|
||||
coeffs[2] = R2YF;
|
||||
}
|
||||
bool operator()(const void *src, int srcStep, void *dst, int dstStep, int cols, int rows) const
|
||||
{
|
||||
return ippiColorToGray ? CV_INSTRUMENT_FUN_IPP(ippiColorToGray, src, srcStep, dst, dstStep, ippiSize(cols, rows), coeffs) >= 0 : false;
|
||||
}
|
||||
private:
|
||||
ippiColor2GrayFunc ippiColorToGray;
|
||||
Ipp32f coeffs[3];
|
||||
};
|
||||
|
||||
#if !IPP_DISABLE_CVTCOLOR_GRAY2BGR_8UC3
|
||||
static IppStatus ippiGrayToRGB_C1C3R(const Ipp8u* pSrc, int srcStep, Ipp8u* pDst, int dstStep, IppiSize roiSize)
|
||||
{
|
||||
return CV_INSTRUMENT_FUN_IPP(ippiGrayToRGB_8u_C1C3R, pSrc, srcStep, pDst, dstStep, roiSize);
|
||||
}
|
||||
#endif
|
||||
static IppStatus ippiGrayToRGB_C1C3R(const Ipp16u* pSrc, int srcStep, Ipp16u* pDst, int dstStep, IppiSize roiSize)
|
||||
{
|
||||
return CV_INSTRUMENT_FUN_IPP(ippiGrayToRGB_16u_C1C3R, pSrc, srcStep, pDst, dstStep, roiSize);
|
||||
}
|
||||
static IppStatus ippiGrayToRGB_C1C3R(const Ipp32f* pSrc, int srcStep, Ipp32f* pDst, int dstStep, IppiSize roiSize)
|
||||
{
|
||||
return CV_INSTRUMENT_FUN_IPP(ippiGrayToRGB_32f_C1C3R, pSrc, srcStep, pDst, dstStep, roiSize);
|
||||
}
|
||||
|
||||
static IppStatus ippiGrayToRGB_C1C4R(const Ipp8u* pSrc, int srcStep, Ipp8u* pDst, int dstStep, IppiSize roiSize, Ipp8u aval)
|
||||
{
|
||||
return CV_INSTRUMENT_FUN_IPP(ippiGrayToRGB_8u_C1C4R, pSrc, srcStep, pDst, dstStep, roiSize, aval);
|
||||
}
|
||||
static IppStatus ippiGrayToRGB_C1C4R(const Ipp16u* pSrc, int srcStep, Ipp16u* pDst, int dstStep, IppiSize roiSize, Ipp16u aval)
|
||||
{
|
||||
return CV_INSTRUMENT_FUN_IPP(ippiGrayToRGB_16u_C1C4R, pSrc, srcStep, pDst, dstStep, roiSize, aval);
|
||||
}
|
||||
static IppStatus ippiGrayToRGB_C1C4R(const Ipp32f* pSrc, int srcStep, Ipp32f* pDst, int dstStep, IppiSize roiSize, Ipp32f aval)
|
||||
{
|
||||
return CV_INSTRUMENT_FUN_IPP(ippiGrayToRGB_32f_C1C4R, pSrc, srcStep, pDst, dstStep, roiSize, aval);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct IPPGray2BGRFunctor
|
||||
{
|
||||
IPPGray2BGRFunctor(){}
|
||||
bool operator()(const void *src, int srcStep, void *dst, int dstStep, int cols, int rows) const
|
||||
{
|
||||
return ippiGrayToRGB_C1C3R((T*)src, srcStep, (T*)dst, dstStep, ippiSize(cols, rows)) >= 0;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct IPPGray2BGRAFunctor
|
||||
{
|
||||
IPPGray2BGRAFunctor()
|
||||
{
|
||||
alpha = ColorChannel<T>::max();
|
||||
}
|
||||
bool operator()(const void *src, int srcStep, void *dst, int dstStep, int cols, int rows) const
|
||||
{
|
||||
return ippiGrayToRGB_C1C4R((T*)src, srcStep, (T*)dst, dstStep, ippiSize(cols, rows), alpha) >= 0;
|
||||
}
|
||||
T alpha;
|
||||
};
|
||||
|
||||
static IppStatus CV_STDCALL ippiSwapChannels_8u_C3C4Rf(const Ipp8u* pSrc, int srcStep, Ipp8u* pDst, int dstStep,
|
||||
IppiSize roiSize, const int *dstOrder)
|
||||
{
|
||||
return CV_INSTRUMENT_FUN_IPP(ippiSwapChannels_8u_C3C4R, pSrc, srcStep, pDst, dstStep, roiSize, dstOrder, MAX_IPP8u);
|
||||
}
|
||||
static IppStatus CV_STDCALL ippiSwapChannels_16u_C3C4Rf(const Ipp16u* pSrc, int srcStep, Ipp16u* pDst, int dstStep,
|
||||
IppiSize roiSize, const int *dstOrder)
|
||||
{
|
||||
return CV_INSTRUMENT_FUN_IPP(ippiSwapChannels_16u_C3C4R, pSrc, srcStep, pDst, dstStep, roiSize, dstOrder, MAX_IPP16u);
|
||||
}
|
||||
static IppStatus CV_STDCALL ippiSwapChannels_32f_C3C4Rf(const Ipp32f* pSrc, int srcStep, Ipp32f* pDst, int dstStep,
|
||||
IppiSize roiSize, const int *dstOrder)
|
||||
{
|
||||
return CV_INSTRUMENT_FUN_IPP(ippiSwapChannels_32f_C3C4R, pSrc, srcStep, pDst, dstStep, roiSize, dstOrder, MAX_IPP32f);
|
||||
}
|
||||
|
||||
static const ippiColor2GrayFunc ippiColor2GrayC3Tab[CV_DEPTH_MAX] =
|
||||
{
|
||||
(ippiColor2GrayFunc)ippiColorToGray_8u_C3C1R, 0, (ippiColor2GrayFunc)ippiColorToGray_16u_C3C1R, 0,
|
||||
0, (ippiColor2GrayFunc)ippiColorToGray_32f_C3C1R, 0, 0
|
||||
};
|
||||
|
||||
static const ippiColor2GrayFunc ippiColor2GrayC4Tab[CV_DEPTH_MAX] =
|
||||
{
|
||||
(ippiColor2GrayFunc)ippiColorToGray_8u_AC4C1R, 0, (ippiColor2GrayFunc)ippiColorToGray_16u_AC4C1R, 0,
|
||||
0, (ippiColor2GrayFunc)ippiColorToGray_32f_AC4C1R, 0, 0
|
||||
};
|
||||
|
||||
static const ippiGeneralFunc ippiRGB2GrayC3Tab[CV_DEPTH_MAX] =
|
||||
{
|
||||
(ippiGeneralFunc)ippiRGBToGray_8u_C3C1R, 0, (ippiGeneralFunc)ippiRGBToGray_16u_C3C1R, 0,
|
||||
0, (ippiGeneralFunc)ippiRGBToGray_32f_C3C1R, 0, 0
|
||||
};
|
||||
|
||||
static const ippiGeneralFunc ippiRGB2GrayC4Tab[CV_DEPTH_MAX] =
|
||||
{
|
||||
(ippiGeneralFunc)ippiRGBToGray_8u_AC4C1R, 0, (ippiGeneralFunc)ippiRGBToGray_16u_AC4C1R, 0,
|
||||
0, (ippiGeneralFunc)ippiRGBToGray_32f_AC4C1R, 0, 0
|
||||
};
|
||||
|
||||
static const ippiReorderFunc ippiSwapChannelsC3C4RTab[CV_DEPTH_MAX] =
|
||||
{
|
||||
(ippiReorderFunc)ippiSwapChannels_8u_C3C4Rf, 0, (ippiReorderFunc)ippiSwapChannels_16u_C3C4Rf, 0,
|
||||
0, (ippiReorderFunc)ippiSwapChannels_32f_C3C4Rf, 0, 0
|
||||
};
|
||||
|
||||
static const ippiGeneralFunc ippiCopyAC4C3RTab[CV_DEPTH_MAX] =
|
||||
{
|
||||
(ippiGeneralFunc)ippiCopy_8u_AC4C3R, 0, (ippiGeneralFunc)ippiCopy_16u_AC4C3R, 0,
|
||||
0, (ippiGeneralFunc)ippiCopy_32f_AC4C3R, 0, 0
|
||||
};
|
||||
|
||||
static const ippiReorderFunc ippiSwapChannelsC4C3RTab[CV_DEPTH_MAX] =
|
||||
{
|
||||
(ippiReorderFunc)ippiSwapChannels_8u_C4C3R, 0, (ippiReorderFunc)ippiSwapChannels_16u_C4C3R, 0,
|
||||
0, (ippiReorderFunc)ippiSwapChannels_32f_C4C3R, 0, 0
|
||||
};
|
||||
|
||||
static const ippiReorderFunc ippiSwapChannelsC3RTab[CV_DEPTH_MAX] =
|
||||
{
|
||||
(ippiReorderFunc)ippiSwapChannels_8u_C3R, 0, (ippiReorderFunc)ippiSwapChannels_16u_C3R, 0,
|
||||
0, (ippiReorderFunc)ippiSwapChannels_32f_C3R, 0, 0
|
||||
};
|
||||
|
||||
#if IPP_VERSION_X100 >= 810
|
||||
static const ippiReorderFunc ippiSwapChannelsC4RTab[CV_DEPTH_MAX] =
|
||||
{
|
||||
(ippiReorderFunc)ippiSwapChannels_8u_C4R, 0, (ippiReorderFunc)ippiSwapChannels_16u_C4R, 0,
|
||||
0, (ippiReorderFunc)ippiSwapChannels_32f_C4R, 0, 0
|
||||
};
|
||||
#endif
|
||||
|
||||
#if !IPP_DISABLE_RGB_HSV
|
||||
static const ippiGeneralFunc ippiRGB2HSVTab[CV_DEPTH_MAX] =
|
||||
{
|
||||
(ippiGeneralFunc)ippiRGBToHSV_8u_C3R, 0, (ippiGeneralFunc)ippiRGBToHSV_16u_C3R, 0,
|
||||
0, 0, 0, 0
|
||||
};
|
||||
#endif
|
||||
|
||||
static const ippiGeneralFunc ippiHSV2RGBTab[CV_DEPTH_MAX] =
|
||||
{
|
||||
(ippiGeneralFunc)ippiHSVToRGB_8u_C3R, 0, (ippiGeneralFunc)ippiHSVToRGB_16u_C3R, 0,
|
||||
0, 0, 0, 0
|
||||
};
|
||||
|
||||
static const ippiGeneralFunc ippiRGB2HLSTab[CV_DEPTH_MAX] =
|
||||
{
|
||||
(ippiGeneralFunc)ippiRGBToHLS_8u_C3R, 0, (ippiGeneralFunc)ippiRGBToHLS_16u_C3R, 0,
|
||||
0, (ippiGeneralFunc)ippiRGBToHLS_32f_C3R, 0, 0
|
||||
};
|
||||
|
||||
static const ippiGeneralFunc ippiHLS2RGBTab[CV_DEPTH_MAX] =
|
||||
{
|
||||
(ippiGeneralFunc)ippiHLSToRGB_8u_C3R, 0, (ippiGeneralFunc)ippiHLSToRGB_16u_C3R, 0,
|
||||
0, (ippiGeneralFunc)ippiHLSToRGB_32f_C3R, 0, 0
|
||||
};
|
||||
|
||||
#if !IPP_DISABLE_RGB_XYZ
|
||||
static const ippiGeneralFunc ippiRGB2XYZTab[CV_DEPTH_MAX] =
|
||||
{
|
||||
(ippiGeneralFunc)ippiRGBToXYZ_8u_C3R, 0, (ippiGeneralFunc)ippiRGBToXYZ_16u_C3R, 0,
|
||||
0, (ippiGeneralFunc)ippiRGBToXYZ_32f_C3R, 0, 0
|
||||
};
|
||||
#endif
|
||||
|
||||
#if !IPP_DISABLE_XYZ_RGB
|
||||
static const ippiGeneralFunc ippiXYZ2RGBTab[CV_DEPTH_MAX] =
|
||||
{
|
||||
(ippiGeneralFunc)ippiXYZToRGB_8u_C3R, 0, (ippiGeneralFunc)ippiXYZToRGB_16u_C3R, 0,
|
||||
0, (ippiGeneralFunc)ippiXYZToRGB_32f_C3R, 0, 0
|
||||
};
|
||||
#endif
|
||||
|
||||
#if !IPP_DISABLE_RGB_LAB
|
||||
static const ippiGeneralFunc ippiRGBToLUVTab[CV_DEPTH_MAX] =
|
||||
{
|
||||
(ippiGeneralFunc)ippiRGBToLUV_8u_C3R, 0, (ippiGeneralFunc)ippiRGBToLUV_16u_C3R, 0,
|
||||
0, (ippiGeneralFunc)ippiRGBToLUV_32f_C3R, 0, 0
|
||||
};
|
||||
#endif
|
||||
|
||||
#if !IPP_DISABLE_LAB_RGB
|
||||
static const ippiGeneralFunc ippiLUVToRGBTab[CV_DEPTH_MAX] =
|
||||
{
|
||||
(ippiGeneralFunc)ippiLUVToRGB_8u_C3R, 0, (ippiGeneralFunc)ippiLUVToRGB_16u_C3R, 0,
|
||||
0, (ippiGeneralFunc)ippiLUVToRGB_32f_C3R, 0, 0
|
||||
};
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
||||
int ipp_hal_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_HAL_CHECK_USE_IPP();
|
||||
|
||||
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 CV_HAL_ERROR_OK;
|
||||
}
|
||||
else if(scn == 4 && dcn == 3 && !swapBlue)
|
||||
{
|
||||
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
|
||||
IPPGeneralFunctor(ippiCopyAC4C3RTab[depth])) )
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
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 CV_HAL_ERROR_OK;
|
||||
}
|
||||
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 CV_HAL_ERROR_OK;
|
||||
}
|
||||
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 CV_HAL_ERROR_OK;
|
||||
}
|
||||
#if IPP_VERSION_X100 >= 810
|
||||
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 CV_HAL_ERROR_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
int ipp_hal_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_HAL_CHECK_USE_IPP();
|
||||
|
||||
bool ippres = false;
|
||||
if(dcn == 3)
|
||||
{
|
||||
if( depth == CV_8U )
|
||||
{
|
||||
#if !IPP_DISABLE_CVTCOLOR_GRAY2BGR_8UC3
|
||||
ippres = CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, IPPGray2BGRFunctor<Ipp8u>());
|
||||
#endif
|
||||
}
|
||||
else if( depth == CV_16U )
|
||||
ippres = CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, IPPGray2BGRFunctor<Ipp16u>());
|
||||
else
|
||||
ippres = CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, IPPGray2BGRFunctor<Ipp32f>());
|
||||
}
|
||||
else if(dcn == 4)
|
||||
{
|
||||
if( depth == CV_8U )
|
||||
ippres = CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, IPPGray2BGRAFunctor<Ipp8u>());
|
||||
else if( depth == CV_16U )
|
||||
ippres = CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, IPPGray2BGRAFunctor<Ipp16u>());
|
||||
else
|
||||
ippres = CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, IPPGray2BGRAFunctor<Ipp32f>());
|
||||
}
|
||||
|
||||
return ippres ? CV_HAL_ERROR_OK : CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
int ipp_hal_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_HAL_CHECK_USE_IPP();
|
||||
|
||||
// preserves original cvtBGRtoGray routing: only 32f was sent to IPP, other depths use the dispatch path
|
||||
if (depth != CV_32F)
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
if(scn == 3 && !swapBlue)
|
||||
{
|
||||
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
|
||||
IPPColor2GrayFunctor(ippiColor2GrayC3Tab[depth])) )
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
else if(scn == 3 && swapBlue)
|
||||
{
|
||||
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
|
||||
IPPGeneralFunctor(ippiRGB2GrayC3Tab[depth])) )
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
else if(scn == 4 && !swapBlue)
|
||||
{
|
||||
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
|
||||
IPPColor2GrayFunctor(ippiColor2GrayC4Tab[depth])) )
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
else if(scn == 4 && swapBlue)
|
||||
{
|
||||
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
|
||||
IPPGeneralFunctor(ippiRGB2GrayC4Tab[depth])) )
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
int ipp_hal_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_HAL_CHECK_USE_IPP();
|
||||
|
||||
if(depth == CV_8U && isFullRange)
|
||||
{
|
||||
if (isHSV)
|
||||
{
|
||||
#if !IPP_DISABLE_RGB_HSV // breaks OCL accuracy tests
|
||||
if(scn == 3 && !swapBlue)
|
||||
{
|
||||
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 CV_HAL_ERROR_OK;
|
||||
}
|
||||
else if(scn == 4 && !swapBlue)
|
||||
{
|
||||
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
|
||||
IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], ippiRGB2HSVTab[depth], 2, 1, 0, depth)) )
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
else if(scn == 4 && swapBlue)
|
||||
{
|
||||
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
|
||||
IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], ippiRGB2HSVTab[depth], 0, 1, 2, depth)) )
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
if(scn == 3 && !swapBlue)
|
||||
{
|
||||
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 CV_HAL_ERROR_OK;
|
||||
}
|
||||
else if(scn == 4 && !swapBlue)
|
||||
{
|
||||
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
|
||||
IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], ippiRGB2HLSTab[depth], 2, 1, 0, depth)) )
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
else if(scn == 3 && swapBlue)
|
||||
{
|
||||
if( CvtColorIPPLoopCopy(src_data, src_step, CV_MAKE_TYPE(depth, scn), dst_data, dst_step, width, height,
|
||||
IPPGeneralFunctor(ippiRGB2HLSTab[depth])) )
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
else if(scn == 4 && swapBlue)
|
||||
{
|
||||
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
|
||||
IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], ippiRGB2HLSTab[depth], 0, 1, 2, depth)) )
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
int ipp_hal_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_HAL_CHECK_USE_IPP();
|
||||
|
||||
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 CV_HAL_ERROR_OK;
|
||||
}
|
||||
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 CV_HAL_ERROR_OK;
|
||||
}
|
||||
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 CV_HAL_ERROR_OK;
|
||||
}
|
||||
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 CV_HAL_ERROR_OK;
|
||||
}
|
||||
}
|
||||
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 CV_HAL_ERROR_OK;
|
||||
}
|
||||
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 CV_HAL_ERROR_OK;
|
||||
}
|
||||
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 CV_HAL_ERROR_OK;
|
||||
}
|
||||
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 CV_HAL_ERROR_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
int ipp_hal_cvtRGBAtoMultipliedRGBA(const uchar * src_data, size_t src_step, uchar * dst_data, size_t dst_step,
|
||||
int width, int height)
|
||||
{
|
||||
CV_HAL_CHECK_USE_IPP();
|
||||
|
||||
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
|
||||
IPPGeneralFunctor((ippiGeneralFunc)ippiAlphaPremul_8u_AC4R)) )
|
||||
return CV_HAL_ERROR_OK;
|
||||
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
#if !IPP_DISABLE_RGB_YUV
|
||||
int ipp_hal_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_HAL_CHECK_USE_IPP();
|
||||
|
||||
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 CV_HAL_ERROR_OK;
|
||||
}
|
||||
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 CV_HAL_ERROR_OK;
|
||||
}
|
||||
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 CV_HAL_ERROR_OK;
|
||||
}
|
||||
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 CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
#endif // !IPP_DISABLE_RGB_YUV
|
||||
|
||||
#if !IPP_DISABLE_YUV_RGB
|
||||
int ipp_hal_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_HAL_CHECK_USE_IPP();
|
||||
|
||||
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 CV_HAL_ERROR_OK;
|
||||
}
|
||||
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 CV_HAL_ERROR_OK;
|
||||
}
|
||||
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 CV_HAL_ERROR_OK;
|
||||
}
|
||||
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 CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
#endif // !IPP_DISABLE_YUV_RGB
|
||||
|
||||
#if !IPP_DISABLE_RGB_XYZ
|
||||
int ipp_hal_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_HAL_CHECK_USE_IPP();
|
||||
|
||||
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 CV_HAL_ERROR_OK;
|
||||
}
|
||||
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 CV_HAL_ERROR_OK;
|
||||
}
|
||||
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 CV_HAL_ERROR_OK;
|
||||
}
|
||||
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 CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
#endif // !IPP_DISABLE_RGB_XYZ
|
||||
|
||||
#if !IPP_DISABLE_XYZ_RGB
|
||||
int ipp_hal_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_HAL_CHECK_USE_IPP();
|
||||
|
||||
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 CV_HAL_ERROR_OK;
|
||||
}
|
||||
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 CV_HAL_ERROR_OK;
|
||||
}
|
||||
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 CV_HAL_ERROR_OK;
|
||||
}
|
||||
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 CV_HAL_ERROR_OK;
|
||||
}
|
||||
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
#endif // !IPP_DISABLE_XYZ_RGB
|
||||
|
||||
#if !IPP_DISABLE_RGB_LAB
|
||||
int ipp_hal_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_HAL_CHECK_USE_IPP();
|
||||
|
||||
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 CV_HAL_ERROR_OK;
|
||||
}
|
||||
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 CV_HAL_ERROR_OK;
|
||||
}
|
||||
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 CV_HAL_ERROR_OK;
|
||||
}
|
||||
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 CV_HAL_ERROR_OK;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (scn == 3 && swapBlue)
|
||||
{
|
||||
if (CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
|
||||
IPPGeneralFunctor(ippiRGBToLUVTab[depth])))
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
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 CV_HAL_ERROR_OK;
|
||||
}
|
||||
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 CV_HAL_ERROR_OK;
|
||||
}
|
||||
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 CV_HAL_ERROR_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
#endif // !IPP_DISABLE_RGB_LAB
|
||||
|
||||
#if !IPP_DISABLE_LAB_RGB
|
||||
int ipp_hal_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_HAL_CHECK_USE_IPP();
|
||||
|
||||
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 CV_HAL_ERROR_OK;
|
||||
}
|
||||
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 CV_HAL_ERROR_OK;
|
||||
}
|
||||
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 CV_HAL_ERROR_OK;
|
||||
}
|
||||
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 CV_HAL_ERROR_OK;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( dcn == 3 && swapBlue)
|
||||
{
|
||||
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
|
||||
IPPGeneralFunctor(ippiLUVToRGBTab[depth])) )
|
||||
return CV_HAL_ERROR_OK;
|
||||
}
|
||||
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 CV_HAL_ERROR_OK;
|
||||
}
|
||||
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 CV_HAL_ERROR_OK;
|
||||
}
|
||||
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 CV_HAL_ERROR_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return CV_HAL_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
#endif // !IPP_DISABLE_LAB_RGB
|
||||
|
||||
#endif // IPP_VERSION_X100 >= 700
|
||||
@@ -23,6 +23,20 @@ static inline IppiSize ippiSize(const cv::Size & _size)
|
||||
return size;
|
||||
}
|
||||
|
||||
#if IPP_VERSION_X100 >= 201700
|
||||
static inline IppiSizeL ippiSizeL(size_t width, size_t height)
|
||||
{
|
||||
IppiSizeL size = { (IppSizeL)width, (IppSizeL)height };
|
||||
return size;
|
||||
}
|
||||
|
||||
static inline IppiSizeL ippiSizeL(const cv::Size & _size)
|
||||
{
|
||||
IppiSizeL size = { _size.width, _size.height };
|
||||
return size;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline IppDataType ippiGetDataType(int depth)
|
||||
{
|
||||
depth = CV_MAT_DEPTH(depth);
|
||||
|
||||
@@ -191,13 +191,6 @@ T* allocSingletonNew() { return new(allocSingletonNewBuffer(sizeof(T))) T(); }
|
||||
#define IPP_DISABLE_PYRAMIDS_DOWN 1 // Different results
|
||||
#define IPP_DISABLE_PYRAMIDS_BUILD 1 // Different results
|
||||
#define IPP_DISABLE_REMAP 1 // Different results
|
||||
#define IPP_DISABLE_YUV_RGB 1 // accuracy difference
|
||||
#define IPP_DISABLE_RGB_YUV 1 // breaks OCL accuracy tests
|
||||
#define IPP_DISABLE_RGB_HSV 1 // breaks OCL accuracy tests
|
||||
#define IPP_DISABLE_RGB_LAB 1 // breaks OCL accuracy tests
|
||||
#define IPP_DISABLE_LAB_RGB 1 // breaks OCL accuracy tests
|
||||
#define IPP_DISABLE_RGB_XYZ 1 // big accuracy difference
|
||||
#define IPP_DISABLE_XYZ_RGB 1 // big accuracy difference
|
||||
#define IPP_DISABLE_HOUGH 1 // improper integration/results
|
||||
#define IPP_DISABLE_FILTER2D_BIG_MASK 1 // different results on masks > 7x7
|
||||
|
||||
|
||||
@@ -333,184 +333,6 @@ struct OclHelper
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if defined (HAVE_IPP) && (IPP_VERSION_X100 >= 700)
|
||||
# define NEED_IPP 1
|
||||
#else
|
||||
# define NEED_IPP 0
|
||||
#endif
|
||||
|
||||
#if NEED_IPP
|
||||
|
||||
#define MAX_IPP8u 255
|
||||
#define MAX_IPP16u 65535
|
||||
#define MAX_IPP32f 1.0
|
||||
|
||||
typedef IppStatus (CV_STDCALL* ippiReorderFunc)(const void *, int, void *, int, IppiSize, const int *);
|
||||
typedef IppStatus (CV_STDCALL* ippiGeneralFunc)(const void *, int, void *, int, IppiSize);
|
||||
typedef IppStatus (CV_STDCALL* ippiColor2GrayFunc)(const void *, int, void *, int, IppiSize, const Ipp32f *);
|
||||
|
||||
template <typename Cvt>
|
||||
class CvtColorIPPLoop_Invoker :
|
||||
public ParallelLoopBody
|
||||
{
|
||||
public:
|
||||
|
||||
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 CV_OVERRIDE
|
||||
{
|
||||
const void *yS = src_data + src_step * range.start;
|
||||
void *yD = dst_data + dst_step * range.start;
|
||||
if( !cvt(yS, static_cast<int>(src_step), yD, static_cast<int>(dst_step), width, range.end - range.start) )
|
||||
*ok = false;
|
||||
else
|
||||
{
|
||||
CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
const uchar * src_data;
|
||||
const size_t src_step;
|
||||
uchar * dst_data;
|
||||
const size_t dst_step;
|
||||
const int width;
|
||||
const Cvt& cvt;
|
||||
bool *ok;
|
||||
|
||||
const CvtColorIPPLoop_Invoker& operator= (const CvtColorIPPLoop_Invoker&);
|
||||
};
|
||||
|
||||
|
||||
template <typename 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, height), CvtColorIPPLoop_Invoker<Cvt>(src_data, src_step, dst_data, dst_step, width, cvt, &ok), (width * height)/(double)(1<<16) );
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
template <typename 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 src(Size(width, height), src_type, const_cast<uchar*>(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<Cvt>(source.data, source.step, dst_data, dst_step,
|
||||
source.cols, cvt, &ok),
|
||||
source.total()/(double)(1<<16) );
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
struct IPPGeneralFunctor
|
||||
{
|
||||
IPPGeneralFunctor(ippiGeneralFunc _func) : ippiColorConvertGeneral(_func){}
|
||||
bool operator()(const void *src, int srcStep, void *dst, int dstStep, int cols, int rows) const
|
||||
{
|
||||
return ippiColorConvertGeneral ? CV_INSTRUMENT_FUN_IPP(ippiColorConvertGeneral, src, srcStep, dst, dstStep, ippiSize(cols, rows)) >= 0 : false;
|
||||
}
|
||||
private:
|
||||
ippiGeneralFunc ippiColorConvertGeneral;
|
||||
};
|
||||
|
||||
|
||||
struct IPPReorderFunctor
|
||||
{
|
||||
IPPReorderFunctor(ippiReorderFunc _func, int _order0, int _order1, int _order2) : ippiColorConvertReorder(_func)
|
||||
{
|
||||
order[0] = _order0;
|
||||
order[1] = _order1;
|
||||
order[2] = _order2;
|
||||
order[3] = 3;
|
||||
}
|
||||
bool operator()(const void *src, int srcStep, void *dst, int dstStep, int cols, int rows) const
|
||||
{
|
||||
return ippiColorConvertReorder ? CV_INSTRUMENT_FUN_IPP(ippiColorConvertReorder, src, srcStep, dst, dstStep, ippiSize(cols, rows), order) >= 0 : false;
|
||||
}
|
||||
private:
|
||||
ippiReorderFunc ippiColorConvertReorder;
|
||||
int order[4];
|
||||
};
|
||||
|
||||
|
||||
struct IPPReorderGeneralFunctor
|
||||
{
|
||||
IPPReorderGeneralFunctor(ippiReorderFunc _func1, ippiGeneralFunc _func2, int _order0, int _order1, int _order2, int _depth) :
|
||||
ippiColorConvertReorder(_func1), ippiColorConvertGeneral(_func2), depth(_depth)
|
||||
{
|
||||
order[0] = _order0;
|
||||
order[1] = _order1;
|
||||
order[2] = _order2;
|
||||
order[3] = 3;
|
||||
}
|
||||
bool operator()(const void *src, int srcStep, void *dst, int dstStep, int cols, int rows) const
|
||||
{
|
||||
if (ippiColorConvertReorder == 0 || ippiColorConvertGeneral == 0)
|
||||
return false;
|
||||
|
||||
Mat temp;
|
||||
temp.create(rows, cols, CV_MAKETYPE(depth, 3));
|
||||
if(CV_INSTRUMENT_FUN_IPP(ippiColorConvertReorder, src, srcStep, temp.ptr(), (int)temp.step[0], ippiSize(cols, rows), order) < 0)
|
||||
return false;
|
||||
return CV_INSTRUMENT_FUN_IPP(ippiColorConvertGeneral, temp.ptr(), (int)temp.step[0], dst, dstStep, ippiSize(cols, rows)) >= 0;
|
||||
}
|
||||
private:
|
||||
ippiReorderFunc ippiColorConvertReorder;
|
||||
ippiGeneralFunc ippiColorConvertGeneral;
|
||||
int order[4];
|
||||
int depth;
|
||||
};
|
||||
|
||||
|
||||
struct IPPGeneralReorderFunctor
|
||||
{
|
||||
IPPGeneralReorderFunctor(ippiGeneralFunc _func1, ippiReorderFunc _func2, int _order0, int _order1, int _order2, int _depth) :
|
||||
ippiColorConvertGeneral(_func1), ippiColorConvertReorder(_func2), depth(_depth)
|
||||
{
|
||||
order[0] = _order0;
|
||||
order[1] = _order1;
|
||||
order[2] = _order2;
|
||||
order[3] = 3;
|
||||
}
|
||||
bool operator()(const void *src, int srcStep, void *dst, int dstStep, int cols, int rows) const
|
||||
{
|
||||
if (ippiColorConvertGeneral == 0 || ippiColorConvertReorder == 0)
|
||||
return false;
|
||||
|
||||
Mat temp;
|
||||
temp.create(rows, cols, CV_MAKETYPE(depth, 3));
|
||||
if(CV_INSTRUMENT_FUN_IPP(ippiColorConvertGeneral, src, srcStep, temp.ptr(), (int)temp.step[0], ippiSize(cols, rows)) < 0)
|
||||
return false;
|
||||
return CV_INSTRUMENT_FUN_IPP(ippiColorConvertReorder, temp.ptr(), (int)temp.step[0], dst, dstStep, ippiSize(cols, rows), order) >= 0;
|
||||
}
|
||||
private:
|
||||
ippiGeneralFunc ippiColorConvertGeneral;
|
||||
ippiReorderFunc ippiColorConvertReorder;
|
||||
int order[4];
|
||||
int depth;
|
||||
};
|
||||
|
||||
extern ippiReorderFunc ippiSwapChannelsC3C4RTab[CV_DEPTH_MAX];
|
||||
extern ippiReorderFunc ippiSwapChannelsC4C3RTab[CV_DEPTH_MAX];
|
||||
extern ippiReorderFunc ippiSwapChannelsC3RTab[CV_DEPTH_MAX];
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENCL
|
||||
|
||||
bool oclCvtColorBGR2Luv( InputArray _src, OutputArray _dst, int bidx, bool srgb );
|
||||
|
||||
@@ -39,6 +39,12 @@ template<> struct ColorChannel<float>
|
||||
static inline float half() { return 0.5f; }
|
||||
};
|
||||
|
||||
// in-place swap; works for sizeless scalable vector types, where std::swap may not compile
|
||||
template<typename _Tp> static inline void v_swap(_Tp& a, _Tp& b)
|
||||
{
|
||||
_Tp t = a; a = b; b = t;
|
||||
}
|
||||
|
||||
/*template<> struct ColorChannel<double>
|
||||
{
|
||||
typedef double worktype_f;
|
||||
@@ -173,4 +179,17 @@ void CvtColorLoop(const uchar * src_data, size_t src_step, uchar * dst_data, siz
|
||||
(width * height) / static_cast<double>(1<<16));
|
||||
}
|
||||
|
||||
// run CvtColorLoop for CV_8U/CV_16U/CV_32F, building the per-depth functor via make(<typed tag>)
|
||||
template <typename MakeCvt> static inline
|
||||
void CvtColorLoopDepth(const uchar * src_data, size_t src_step, uchar * dst_data, size_t dst_step,
|
||||
int width, int height, int depth, const MakeCvt& make)
|
||||
{
|
||||
if( depth == CV_8U )
|
||||
CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, make(uchar(0)));
|
||||
else if( depth == CV_16U )
|
||||
CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, make(ushort(0)));
|
||||
else
|
||||
CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, make(float(0)));
|
||||
}
|
||||
|
||||
} //namespace
|
||||
|
||||
@@ -13,40 +13,6 @@
|
||||
|
||||
namespace cv {
|
||||
|
||||
//
|
||||
// IPP functions
|
||||
//
|
||||
|
||||
#if NEED_IPP
|
||||
|
||||
#if !IPP_DISABLE_RGB_HSV
|
||||
static ippiGeneralFunc ippiRGB2HSVTab[CV_DEPTH_MAX] =
|
||||
{
|
||||
(ippiGeneralFunc)ippiRGBToHSV_8u_C3R, 0, (ippiGeneralFunc)ippiRGBToHSV_16u_C3R, 0,
|
||||
0, 0, 0, 0
|
||||
};
|
||||
#endif
|
||||
|
||||
static ippiGeneralFunc ippiHSV2RGBTab[CV_DEPTH_MAX] =
|
||||
{
|
||||
(ippiGeneralFunc)ippiHSVToRGB_8u_C3R, 0, (ippiGeneralFunc)ippiHSVToRGB_16u_C3R, 0,
|
||||
0, 0, 0, 0
|
||||
};
|
||||
|
||||
static ippiGeneralFunc ippiRGB2HLSTab[CV_DEPTH_MAX] =
|
||||
{
|
||||
(ippiGeneralFunc)ippiRGBToHLS_8u_C3R, 0, (ippiGeneralFunc)ippiRGBToHLS_16u_C3R, 0,
|
||||
0, (ippiGeneralFunc)ippiRGBToHLS_32f_C3R, 0, 0
|
||||
};
|
||||
|
||||
static ippiGeneralFunc ippiHLS2RGBTab[CV_DEPTH_MAX] =
|
||||
{
|
||||
(ippiGeneralFunc)ippiHLSToRGB_8u_C3R, 0, (ippiGeneralFunc)ippiHLSToRGB_16u_C3R, 0,
|
||||
0, (ippiGeneralFunc)ippiHLSToRGB_32f_C3R, 0, 0
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
// HAL functions
|
||||
//
|
||||
@@ -64,65 +30,6 @@ void cvtBGRtoHSV(const uchar * src_data, size_t src_step,
|
||||
|
||||
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_RGB_HSV // breaks OCL accuracy tests
|
||||
if(scn == 3 && !swapBlue)
|
||||
{
|
||||
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(scn == 4 && !swapBlue)
|
||||
{
|
||||
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
|
||||
IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], ippiRGB2HSVTab[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], ippiRGB2HSVTab[depth], 0, 1, 2, depth)) )
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
if(scn == 3 && !swapBlue)
|
||||
{
|
||||
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(scn == 4 && !swapBlue)
|
||||
{
|
||||
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
|
||||
IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], ippiRGB2HLSTab[depth], 2, 1, 0, depth)) )
|
||||
return;
|
||||
}
|
||||
else if(scn == 3 && swapBlue)
|
||||
{
|
||||
if( CvtColorIPPLoopCopy(src_data, src_step, CV_MAKE_TYPE(depth, scn), dst_data, dst_step, width, height,
|
||||
IPPGeneralFunctor(ippiRGB2HLSTab[depth])) )
|
||||
return;
|
||||
}
|
||||
else if(scn == 4 && swapBlue)
|
||||
{
|
||||
if( CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height,
|
||||
IPPReorderGeneralFunctor(ippiSwapChannelsC4C3RTab[depth], ippiRGB2HLSTab[depth], 0, 1, 2, depth)) )
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
CV_CPU_DISPATCH(cvtBGRtoHSV, (src_data, src_step, dst_data, dst_step, width, height, depth, scn, swapBlue, isFullRange, isHSV),
|
||||
CV_CPU_DISPATCH_MODES_ALL);
|
||||
}
|
||||
@@ -137,69 +44,6 @@ void cvtHSVtoBGR(const uchar * src_data, size_t src_step,
|
||||
|
||||
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
|
||||
|
||||
CV_CPU_DISPATCH(cvtHSVtoBGR, (src_data, src_step, dst_data, dst_step, width, height, depth, dcn, swapBlue, isFullRange, isHSV),
|
||||
CV_CPU_DISPATCH_MODES_ALL);
|
||||
}
|
||||
|
||||
@@ -5,19 +5,6 @@
|
||||
#include "precomp.hpp"
|
||||
#include "opencv2/core/hal/intrin.hpp"
|
||||
|
||||
#if CV_SIMD_SCALABLE
|
||||
/* FIX IT:
|
||||
// std::swap(a, b) is not available for RVV vector types,
|
||||
// and CV_SWAP needs another "t" as input,
|
||||
// For compatibility, we swap RVV vector manually by using this macro.
|
||||
|
||||
// If others scalable types (e.g. type in ARM SVE) can use std::swap,
|
||||
// then replace CV_SIMD_SCALABLE with CV_RVV.
|
||||
// If std::swap is available for RVV vector types in future, remove this macro.
|
||||
*/
|
||||
#define swap(a, b) {auto t = a; a = b; b = t;}
|
||||
#endif
|
||||
|
||||
namespace cv {
|
||||
namespace hal {
|
||||
CV_CPU_OPTIMIZATION_NAMESPACE_BEGIN
|
||||
@@ -115,7 +102,7 @@ struct RGB2HSV_b
|
||||
}
|
||||
|
||||
if(bidx)
|
||||
swap(b, r);
|
||||
v_swap(b, r);
|
||||
|
||||
v_uint8 h, s, v;
|
||||
v_uint8 vmin;
|
||||
@@ -323,7 +310,7 @@ struct RGB2HSV_f
|
||||
}
|
||||
|
||||
if(bidx)
|
||||
swap(b, r);
|
||||
v_swap(b, r);
|
||||
|
||||
v_float32 h, s, v;
|
||||
process(b, g, r, h, s, v, hscale);
|
||||
@@ -484,7 +471,7 @@ struct HSV2RGB_f
|
||||
HSV2RGB_simd(h, s, v, b, g, r, hs);
|
||||
|
||||
if(bidx)
|
||||
swap(b, r);
|
||||
v_swap(b, r);
|
||||
|
||||
if(dcn == 4)
|
||||
{
|
||||
@@ -738,7 +725,7 @@ struct RGB2HLS_f
|
||||
}
|
||||
|
||||
if(bidx)
|
||||
swap(r, b);
|
||||
v_swap(r, b);
|
||||
|
||||
process(r, g, b, vhscale, h, l, s);
|
||||
|
||||
@@ -1026,7 +1013,7 @@ struct HLS2RGB_f
|
||||
process(h, l, s, b, g, r);
|
||||
|
||||
if(bidx)
|
||||
swap(b, r);
|
||||
v_swap(b, r);
|
||||
|
||||
if(dcn == 3)
|
||||
{
|
||||
|
||||
@@ -95,6 +95,20 @@ template<typename _Tp> static inline cv::v_float32 splineInterpolate(const cv::v
|
||||
namespace cv
|
||||
{
|
||||
|
||||
// swap R<->B in a row-major 3x3 coeff matrix when blueIdx==0
|
||||
template<typename CT> static inline void swapBlueCoeffsCols(CT* coeffs)
|
||||
{
|
||||
std::swap(coeffs[0], coeffs[2]);
|
||||
std::swap(coeffs[3], coeffs[5]);
|
||||
std::swap(coeffs[6], coeffs[8]);
|
||||
}
|
||||
template<typename CT> static inline void swapBlueCoeffsRows(CT* coeffs)
|
||||
{
|
||||
std::swap(coeffs[0], coeffs[6]);
|
||||
std::swap(coeffs[1], coeffs[7]);
|
||||
std::swap(coeffs[2], coeffs[8]);
|
||||
}
|
||||
|
||||
////////////////////////////////////// RGB <-> XYZ ///////////////////////////////////////
|
||||
|
||||
// 0.412453, 0.357580, 0.180423,
|
||||
@@ -152,11 +166,7 @@ template<typename _Tp> struct RGB2XYZ_f
|
||||
for(int i = 0; i < 9; i++)
|
||||
coeffs[i] = _coeffs ? _coeffs[i] : (float)sRGB2XYZ_D65[i];
|
||||
if(blueIdx == 0)
|
||||
{
|
||||
std::swap(coeffs[0], coeffs[2]);
|
||||
std::swap(coeffs[3], coeffs[5]);
|
||||
std::swap(coeffs[6], coeffs[8]);
|
||||
}
|
||||
swapBlueCoeffsCols(coeffs);
|
||||
}
|
||||
void operator()(const _Tp* src, _Tp* dst, int n) const
|
||||
{
|
||||
@@ -189,11 +199,7 @@ struct RGB2XYZ_f<float>
|
||||
for(int i = 0; i < 9; i++)
|
||||
coeffs[i] = _coeffs ? _coeffs[i] : (float)sRGB2XYZ_D65[i];
|
||||
if(blueIdx == 0)
|
||||
{
|
||||
std::swap(coeffs[0], coeffs[2]);
|
||||
std::swap(coeffs[3], coeffs[5]);
|
||||
std::swap(coeffs[6], coeffs[8]);
|
||||
}
|
||||
swapBlueCoeffsCols(coeffs);
|
||||
}
|
||||
|
||||
void operator()(const float* src, float* dst, int n) const
|
||||
@@ -257,11 +263,7 @@ template<typename _Tp> struct RGB2XYZ_i
|
||||
for( int i = 0; i < 9; i++ )
|
||||
coeffs[i] = _coeffs ? cvRound(_coeffs[i]*(1 << xyz_shift)) : sRGB2XYZ_D65_i[i];
|
||||
if(blueIdx == 0)
|
||||
{
|
||||
std::swap(coeffs[0], coeffs[2]);
|
||||
std::swap(coeffs[3], coeffs[5]);
|
||||
std::swap(coeffs[6], coeffs[8]);
|
||||
}
|
||||
swapBlueCoeffsCols(coeffs);
|
||||
}
|
||||
void operator()(const _Tp* src, _Tp* dst, int n) const
|
||||
{
|
||||
@@ -296,11 +298,7 @@ struct RGB2XYZ_i<uchar>
|
||||
for( int i = 0; i < 9; i++ )
|
||||
coeffs[i] = _coeffs ? cvRound(_coeffs[i]*(1 << shift)) : sRGB2XYZ_D65_i[i];
|
||||
if(blueIdx == 0)
|
||||
{
|
||||
std::swap(coeffs[0], coeffs[2]);
|
||||
std::swap(coeffs[3], coeffs[5]);
|
||||
std::swap(coeffs[6], coeffs[8]);
|
||||
}
|
||||
swapBlueCoeffsCols(coeffs);
|
||||
}
|
||||
void operator()(const uchar * src, uchar * dst, int n) const
|
||||
{
|
||||
@@ -416,11 +414,7 @@ struct RGB2XYZ_i<ushort>
|
||||
for( int i = 0; i < 9; i++ )
|
||||
coeffs[i] = _coeffs ? cvRound(_coeffs[i]*(1 << shift)) : sRGB2XYZ_D65_i[i];
|
||||
if(blueIdx == 0)
|
||||
{
|
||||
std::swap(coeffs[0], coeffs[2]);
|
||||
std::swap(coeffs[3], coeffs[5]);
|
||||
std::swap(coeffs[6], coeffs[8]);
|
||||
}
|
||||
swapBlueCoeffsCols(coeffs);
|
||||
}
|
||||
|
||||
void operator()(const ushort * src, ushort * dst, int n) const
|
||||
@@ -542,11 +536,7 @@ template<typename _Tp> struct XYZ2RGB_f
|
||||
for(int i = 0; i < 9; i++)
|
||||
coeffs[i] = _coeffs ? _coeffs[i] : (float)XYZ2sRGB_D65[i];
|
||||
if(blueIdx == 0)
|
||||
{
|
||||
std::swap(coeffs[0], coeffs[6]);
|
||||
std::swap(coeffs[1], coeffs[7]);
|
||||
std::swap(coeffs[2], coeffs[8]);
|
||||
}
|
||||
swapBlueCoeffsRows(coeffs);
|
||||
}
|
||||
|
||||
void operator()(const _Tp* src, _Tp* dst, int n) const
|
||||
@@ -583,11 +573,7 @@ struct XYZ2RGB_f<float>
|
||||
for(int i = 0; i < 9; i++)
|
||||
coeffs[i] = _coeffs ? _coeffs[i] : (float)XYZ2sRGB_D65[i];
|
||||
if(blueIdx == 0)
|
||||
{
|
||||
std::swap(coeffs[0], coeffs[6]);
|
||||
std::swap(coeffs[1], coeffs[7]);
|
||||
std::swap(coeffs[2], coeffs[8]);
|
||||
}
|
||||
swapBlueCoeffsRows(coeffs);
|
||||
}
|
||||
|
||||
void operator()(const float* src, float* dst, int n) const
|
||||
@@ -655,11 +641,7 @@ template<typename _Tp> struct XYZ2RGB_i
|
||||
coeffs[i] = _coeffs ? cvRound(_coeffs[i]*(1 << xyz_shift)) : XYZ2sRGB_D65_i[i];
|
||||
|
||||
if(blueIdx == 0)
|
||||
{
|
||||
std::swap(coeffs[0], coeffs[6]);
|
||||
std::swap(coeffs[1], coeffs[7]);
|
||||
std::swap(coeffs[2], coeffs[8]);
|
||||
}
|
||||
swapBlueCoeffsRows(coeffs);
|
||||
}
|
||||
void operator()(const _Tp* src, _Tp* dst, int n) const
|
||||
{
|
||||
@@ -698,11 +680,7 @@ struct XYZ2RGB_i<uchar>
|
||||
coeffs[i] = _coeffs ? cvRound(_coeffs[i]*(1 << shift)) : XYZ2sRGB_D65_i[i];
|
||||
|
||||
if(blueIdx == 0)
|
||||
{
|
||||
std::swap(coeffs[0], coeffs[6]);
|
||||
std::swap(coeffs[1], coeffs[7]);
|
||||
std::swap(coeffs[2], coeffs[8]);
|
||||
}
|
||||
swapBlueCoeffsRows(coeffs);
|
||||
}
|
||||
|
||||
void operator()(const uchar* src, uchar* dst, int n) const
|
||||
@@ -821,11 +799,7 @@ struct XYZ2RGB_i<ushort>
|
||||
coeffs[i] = _coeffs ? cvRound(_coeffs[i]*(1 << shift)) : XYZ2sRGB_D65_i[i];
|
||||
|
||||
if(blueIdx == 0)
|
||||
{
|
||||
std::swap(coeffs[0], coeffs[6]);
|
||||
std::swap(coeffs[1], coeffs[7]);
|
||||
std::swap(coeffs[2], coeffs[8]);
|
||||
}
|
||||
swapBlueCoeffsRows(coeffs);
|
||||
}
|
||||
|
||||
void operator()(const ushort* src, ushort* dst, int n) const
|
||||
@@ -4076,47 +4050,6 @@ struct Luv2RGB_b
|
||||
bool useBitExactness;
|
||||
};
|
||||
|
||||
//
|
||||
// IPP functions
|
||||
//
|
||||
|
||||
#if NEED_IPP
|
||||
|
||||
#if !IPP_DISABLE_RGB_XYZ
|
||||
static ippiGeneralFunc ippiRGB2XYZTab[CV_DEPTH_MAX] =
|
||||
{
|
||||
(ippiGeneralFunc)ippiRGBToXYZ_8u_C3R, 0, (ippiGeneralFunc)ippiRGBToXYZ_16u_C3R, 0,
|
||||
0, (ippiGeneralFunc)ippiRGBToXYZ_32f_C3R, 0, 0
|
||||
};
|
||||
#endif
|
||||
|
||||
#if !IPP_DISABLE_XYZ_RGB
|
||||
static ippiGeneralFunc ippiXYZ2RGBTab[CV_DEPTH_MAX] =
|
||||
{
|
||||
(ippiGeneralFunc)ippiXYZToRGB_8u_C3R, 0, (ippiGeneralFunc)ippiXYZToRGB_16u_C3R, 0,
|
||||
0, (ippiGeneralFunc)ippiXYZToRGB_32f_C3R, 0, 0
|
||||
};
|
||||
#endif
|
||||
|
||||
#if !IPP_DISABLE_RGB_LAB
|
||||
static ippiGeneralFunc ippiRGBToLUVTab[CV_DEPTH_MAX] =
|
||||
{
|
||||
(ippiGeneralFunc)ippiRGBToLUV_8u_C3R, 0, (ippiGeneralFunc)ippiRGBToLUV_16u_C3R, 0,
|
||||
0, (ippiGeneralFunc)ippiRGBToLUV_32f_C3R, 0, 0
|
||||
};
|
||||
#endif
|
||||
|
||||
#if !IPP_DISABLE_LAB_RGB
|
||||
static ippiGeneralFunc ippiLUVToRGBTab[CV_DEPTH_MAX] =
|
||||
{
|
||||
(ippiGeneralFunc)ippiLUVToRGB_8u_C3R, 0, (ippiGeneralFunc)ippiLUVToRGB_16u_C3R, 0,
|
||||
0, (ippiGeneralFunc)ippiLUVToRGB_32f_C3R, 0, 0
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
//
|
||||
// HAL functions
|
||||
//
|
||||
@@ -4133,38 +4066,6 @@ void cvtBGRtoXYZ(const uchar * src_data, size_t src_step,
|
||||
|
||||
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
|
||||
#if !IPP_DISABLE_RGB_XYZ
|
||||
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
|
||||
#endif
|
||||
|
||||
int blueIdx = swapBlue ? 2 : 0;
|
||||
if( depth == CV_8U )
|
||||
CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, RGB2XYZ_i<uchar>(scn, blueIdx, 0));
|
||||
@@ -4184,38 +4085,6 @@ void cvtXYZtoBGR(const uchar * src_data, size_t src_step,
|
||||
|
||||
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
|
||||
#if !IPP_DISABLE_XYZ_RGB
|
||||
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
|
||||
#endif
|
||||
|
||||
int blueIdx = swapBlue ? 2 : 0;
|
||||
if( depth == CV_8U )
|
||||
CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, XYZ2RGB_i<uchar>(dcn, blueIdx, 0));
|
||||
@@ -4236,75 +4105,6 @@ void cvtBGRtoLab(const uchar * src_data, size_t src_step,
|
||||
|
||||
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_RGB_LAB
|
||||
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)
|
||||
{
|
||||
@@ -4333,75 +4133,6 @@ void cvtLabtoBGR(const uchar * src_data, size_t src_step,
|
||||
|
||||
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_LAB_RGB
|
||||
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)
|
||||
{
|
||||
@@ -4714,11 +4445,7 @@ bool oclCvtColorBGR2XYZ( InputArray _src, OutputArray _dst, int bidx )
|
||||
for(int i = 0; i < 9; i++)
|
||||
coeffs[i] = (float)sRGB2XYZ_D65[i];
|
||||
if (bidx == 0)
|
||||
{
|
||||
std::swap(coeffs[0], coeffs[2]);
|
||||
std::swap(coeffs[3], coeffs[5]);
|
||||
std::swap(coeffs[6], coeffs[8]);
|
||||
}
|
||||
swapBlueCoeffsCols(coeffs);
|
||||
Mat(1, 9, CV_32FC1, &coeffs[0]).copyTo(c);
|
||||
}
|
||||
else
|
||||
@@ -4727,11 +4454,7 @@ bool oclCvtColorBGR2XYZ( InputArray _src, OutputArray _dst, int bidx )
|
||||
for(int i = 0; i < 9; i++)
|
||||
coeffs[i] = sRGB2XYZ_D65_i[i];
|
||||
if (bidx == 0)
|
||||
{
|
||||
std::swap(coeffs[0], coeffs[2]);
|
||||
std::swap(coeffs[3], coeffs[5]);
|
||||
std::swap(coeffs[6], coeffs[8]);
|
||||
}
|
||||
swapBlueCoeffsCols(coeffs);
|
||||
Mat(1, 9, CV_32SC1, &coeffs[0]).copyTo(c);
|
||||
}
|
||||
|
||||
@@ -4762,11 +4485,7 @@ bool oclCvtColorXYZ2BGR( InputArray _src, OutputArray _dst, int dcn, int bidx )
|
||||
for(int i = 0; i < 9; i++)
|
||||
coeffs[i] = (float)XYZ2sRGB_D65[i];
|
||||
if (bidx == 0)
|
||||
{
|
||||
std::swap(coeffs[0], coeffs[6]);
|
||||
std::swap(coeffs[1], coeffs[7]);
|
||||
std::swap(coeffs[2], coeffs[8]);
|
||||
}
|
||||
swapBlueCoeffsRows(coeffs);
|
||||
Mat(1, 9, CV_32FC1, &coeffs[0]).copyTo(c);
|
||||
}
|
||||
else
|
||||
@@ -4775,11 +4494,7 @@ bool oclCvtColorXYZ2BGR( InputArray _src, OutputArray _dst, int dcn, int bidx )
|
||||
for(int i = 0; i < 9; i++)
|
||||
coeffs[i] = XYZ2sRGB_D65_i[i];
|
||||
if (bidx == 0)
|
||||
{
|
||||
std::swap(coeffs[0], coeffs[6]);
|
||||
std::swap(coeffs[1], coeffs[7]);
|
||||
std::swap(coeffs[2], coeffs[8]);
|
||||
}
|
||||
swapBlueCoeffsRows(coeffs);
|
||||
Mat(1, 9, CV_32SC1, &coeffs[0]).copyTo(c);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,169 +10,8 @@
|
||||
#include "color_rgb.simd.hpp"
|
||||
#include "color_rgb.simd_declarations.hpp" // defines CV_CPU_DISPATCH_MODES_ALL=AVX2,...,BASELINE based on CMakeLists.txt content
|
||||
|
||||
#define IPP_DISABLE_CVTCOLOR_GRAY2BGR_8UC3 1
|
||||
|
||||
namespace cv {
|
||||
|
||||
//
|
||||
// IPP functions
|
||||
//
|
||||
|
||||
#if NEED_IPP
|
||||
|
||||
static const ippiColor2GrayFunc ippiColor2GrayC3Tab[CV_DEPTH_MAX] =
|
||||
{
|
||||
(ippiColor2GrayFunc)ippiColorToGray_8u_C3C1R, 0, (ippiColor2GrayFunc)ippiColorToGray_16u_C3C1R, 0,
|
||||
0, (ippiColor2GrayFunc)ippiColorToGray_32f_C3C1R, 0, 0
|
||||
};
|
||||
|
||||
static const ippiColor2GrayFunc ippiColor2GrayC4Tab[CV_DEPTH_MAX] =
|
||||
{
|
||||
(ippiColor2GrayFunc)ippiColorToGray_8u_AC4C1R, 0, (ippiColor2GrayFunc)ippiColorToGray_16u_AC4C1R, 0,
|
||||
0, (ippiColor2GrayFunc)ippiColorToGray_32f_AC4C1R, 0, 0
|
||||
};
|
||||
|
||||
static const ippiGeneralFunc ippiRGB2GrayC3Tab[CV_DEPTH_MAX] =
|
||||
{
|
||||
(ippiGeneralFunc)ippiRGBToGray_8u_C3C1R, 0, (ippiGeneralFunc)ippiRGBToGray_16u_C3C1R, 0,
|
||||
0, (ippiGeneralFunc)ippiRGBToGray_32f_C3C1R, 0, 0
|
||||
};
|
||||
|
||||
static const ippiGeneralFunc ippiRGB2GrayC4Tab[CV_DEPTH_MAX] =
|
||||
{
|
||||
(ippiGeneralFunc)ippiRGBToGray_8u_AC4C1R, 0, (ippiGeneralFunc)ippiRGBToGray_16u_AC4C1R, 0,
|
||||
0, (ippiGeneralFunc)ippiRGBToGray_32f_AC4C1R, 0, 0
|
||||
};
|
||||
|
||||
|
||||
#if !IPP_DISABLE_CVTCOLOR_GRAY2BGR_8UC3
|
||||
static IppStatus ippiGrayToRGB_C1C3R(const Ipp8u* pSrc, int srcStep, Ipp8u* pDst, int dstStep, IppiSize roiSize)
|
||||
{
|
||||
return CV_INSTRUMENT_FUN_IPP(ippiGrayToRGB_8u_C1C3R, pSrc, srcStep, pDst, dstStep, roiSize);
|
||||
}
|
||||
#endif
|
||||
static IppStatus ippiGrayToRGB_C1C3R(const Ipp16u* pSrc, int srcStep, Ipp16u* pDst, int dstStep, IppiSize roiSize)
|
||||
{
|
||||
return CV_INSTRUMENT_FUN_IPP(ippiGrayToRGB_16u_C1C3R, pSrc, srcStep, pDst, dstStep, roiSize);
|
||||
}
|
||||
static IppStatus ippiGrayToRGB_C1C3R(const Ipp32f* pSrc, int srcStep, Ipp32f* pDst, int dstStep, IppiSize roiSize)
|
||||
{
|
||||
return CV_INSTRUMENT_FUN_IPP(ippiGrayToRGB_32f_C1C3R, pSrc, srcStep, pDst, dstStep, roiSize);
|
||||
}
|
||||
|
||||
static IppStatus ippiGrayToRGB_C1C4R(const Ipp8u* pSrc, int srcStep, Ipp8u* pDst, int dstStep, IppiSize roiSize, Ipp8u aval)
|
||||
{
|
||||
return CV_INSTRUMENT_FUN_IPP(ippiGrayToRGB_8u_C1C4R, pSrc, srcStep, pDst, dstStep, roiSize, aval);
|
||||
}
|
||||
static IppStatus ippiGrayToRGB_C1C4R(const Ipp16u* pSrc, int srcStep, Ipp16u* pDst, int dstStep, IppiSize roiSize, Ipp16u aval)
|
||||
{
|
||||
return CV_INSTRUMENT_FUN_IPP(ippiGrayToRGB_16u_C1C4R, pSrc, srcStep, pDst, dstStep, roiSize, aval);
|
||||
}
|
||||
static IppStatus ippiGrayToRGB_C1C4R(const Ipp32f* pSrc, int srcStep, Ipp32f* pDst, int dstStep, IppiSize roiSize, Ipp32f aval)
|
||||
{
|
||||
return CV_INSTRUMENT_FUN_IPP(ippiGrayToRGB_32f_C1C4R, pSrc, srcStep, pDst, dstStep, roiSize, aval);
|
||||
}
|
||||
|
||||
struct IPPColor2GrayFunctor
|
||||
{
|
||||
IPPColor2GrayFunctor(ippiColor2GrayFunc _func) :
|
||||
ippiColorToGray(_func)
|
||||
{
|
||||
coeffs[0] = B2YF;
|
||||
coeffs[1] = G2YF;
|
||||
coeffs[2] = R2YF;
|
||||
}
|
||||
bool operator()(const void *src, int srcStep, void *dst, int dstStep, int cols, int rows) const
|
||||
{
|
||||
return ippiColorToGray ? CV_INSTRUMENT_FUN_IPP(ippiColorToGray, src, srcStep, dst, dstStep, ippiSize(cols, rows), coeffs) >= 0 : false;
|
||||
}
|
||||
private:
|
||||
ippiColor2GrayFunc ippiColorToGray;
|
||||
Ipp32f coeffs[3];
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct IPPGray2BGRFunctor
|
||||
{
|
||||
IPPGray2BGRFunctor(){}
|
||||
|
||||
bool operator()(const void *src, int srcStep, void *dst, int dstStep, int cols, int rows) const
|
||||
{
|
||||
return ippiGrayToRGB_C1C3R((T*)src, srcStep, (T*)dst, dstStep, ippiSize(cols, rows)) >= 0;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct IPPGray2BGRAFunctor
|
||||
{
|
||||
IPPGray2BGRAFunctor()
|
||||
{
|
||||
alpha = ColorChannel<T>::max();
|
||||
}
|
||||
|
||||
bool operator()(const void *src, int srcStep, void *dst, int dstStep, int cols, int rows) const
|
||||
{
|
||||
return ippiGrayToRGB_C1C4R((T*)src, srcStep, (T*)dst, dstStep, ippiSize(cols, rows), alpha) >= 0;
|
||||
}
|
||||
|
||||
T alpha;
|
||||
};
|
||||
|
||||
static IppStatus CV_STDCALL ippiSwapChannels_8u_C3C4Rf(const Ipp8u* pSrc, int srcStep, Ipp8u* pDst, int dstStep,
|
||||
IppiSize roiSize, const int *dstOrder)
|
||||
{
|
||||
return CV_INSTRUMENT_FUN_IPP(ippiSwapChannels_8u_C3C4R, pSrc, srcStep, pDst, dstStep, roiSize, dstOrder, MAX_IPP8u);
|
||||
}
|
||||
|
||||
static IppStatus CV_STDCALL ippiSwapChannels_16u_C3C4Rf(const Ipp16u* pSrc, int srcStep, Ipp16u* pDst, int dstStep,
|
||||
IppiSize roiSize, const int *dstOrder)
|
||||
{
|
||||
return CV_INSTRUMENT_FUN_IPP(ippiSwapChannels_16u_C3C4R, pSrc, srcStep, pDst, dstStep, roiSize, dstOrder, MAX_IPP16u);
|
||||
}
|
||||
|
||||
static IppStatus CV_STDCALL ippiSwapChannels_32f_C3C4Rf(const Ipp32f* pSrc, int srcStep, Ipp32f* pDst, int dstStep,
|
||||
IppiSize roiSize, const int *dstOrder)
|
||||
{
|
||||
return CV_INSTRUMENT_FUN_IPP(ippiSwapChannels_32f_C3C4R, pSrc, srcStep, pDst, dstStep, roiSize, dstOrder, MAX_IPP32f);
|
||||
}
|
||||
|
||||
// shared
|
||||
ippiReorderFunc ippiSwapChannelsC3C4RTab[CV_DEPTH_MAX] =
|
||||
{
|
||||
(ippiReorderFunc)ippiSwapChannels_8u_C3C4Rf, 0, (ippiReorderFunc)ippiSwapChannels_16u_C3C4Rf, 0,
|
||||
0, (ippiReorderFunc)ippiSwapChannels_32f_C3C4Rf, 0, 0
|
||||
};
|
||||
|
||||
static ippiGeneralFunc ippiCopyAC4C3RTab[CV_DEPTH_MAX] =
|
||||
{
|
||||
(ippiGeneralFunc)ippiCopy_8u_AC4C3R, 0, (ippiGeneralFunc)ippiCopy_16u_AC4C3R, 0,
|
||||
0, (ippiGeneralFunc)ippiCopy_32f_AC4C3R, 0, 0
|
||||
};
|
||||
|
||||
// shared
|
||||
ippiReorderFunc ippiSwapChannelsC4C3RTab[CV_DEPTH_MAX] =
|
||||
{
|
||||
(ippiReorderFunc)ippiSwapChannels_8u_C4C3R, 0, (ippiReorderFunc)ippiSwapChannels_16u_C4C3R, 0,
|
||||
0, (ippiReorderFunc)ippiSwapChannels_32f_C4C3R, 0, 0
|
||||
};
|
||||
|
||||
// shared
|
||||
ippiReorderFunc ippiSwapChannelsC3RTab[CV_DEPTH_MAX] =
|
||||
{
|
||||
(ippiReorderFunc)ippiSwapChannels_8u_C3R, 0, (ippiReorderFunc)ippiSwapChannels_16u_C3R, 0,
|
||||
0, (ippiReorderFunc)ippiSwapChannels_32f_C3R, 0, 0
|
||||
};
|
||||
|
||||
#if IPP_VERSION_X100 >= 810
|
||||
static ippiReorderFunc ippiSwapChannelsC4RTab[CV_DEPTH_MAX] =
|
||||
{
|
||||
(ippiReorderFunc)ippiSwapChannels_8u_C4R, 0, (ippiReorderFunc)ippiSwapChannels_16u_C4R, 0,
|
||||
0, (ippiReorderFunc)ippiSwapChannels_32f_C4R, 0, 0
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
// HAL functions
|
||||
//
|
||||
@@ -189,50 +28,6 @@ void cvtBGRtoBGR(const uchar * src_data, size_t src_step,
|
||||
|
||||
CALL_HAL(cvtBGRtoBGR, cv_hal_cvtBGRtoBGR, src_data, src_step, dst_data, dst_step, width, height, depth, scn, dcn, swapBlue);
|
||||
|
||||
#if defined(HAVE_IPP) && IPP_VERSION_X100 >= 700
|
||||
CV_IPP_CHECK()
|
||||
{
|
||||
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(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
|
||||
#endif
|
||||
|
||||
CV_CPU_DISPATCH(cvtBGRtoBGR, (src_data, src_step, dst_data, dst_step, width, height, depth, scn, dcn, swapBlue),
|
||||
CV_CPU_DISPATCH_MODES_ALL);
|
||||
}
|
||||
@@ -275,36 +70,6 @@ void cvtBGRtoGray(const uchar * src_data, size_t src_step,
|
||||
|
||||
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
|
||||
|
||||
CV_CPU_DISPATCH(cvtBGRtoGray, (src_data, src_step, dst_data, dst_step, width, height, depth, scn, swapBlue),
|
||||
CV_CPU_DISPATCH_MODES_ALL);
|
||||
}
|
||||
@@ -319,37 +84,6 @@ void cvtGraytoBGR(const uchar * src_data, size_t src_step,
|
||||
|
||||
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()
|
||||
{
|
||||
bool ippres = false;
|
||||
if(dcn == 3)
|
||||
{
|
||||
if( depth == CV_8U )
|
||||
{
|
||||
#if !IPP_DISABLE_CVTCOLOR_GRAY2BGR_8UC3
|
||||
ippres = CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, IPPGray2BGRFunctor<Ipp8u>());
|
||||
#endif
|
||||
}
|
||||
else if( depth == CV_16U )
|
||||
ippres = CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, IPPGray2BGRFunctor<Ipp16u>());
|
||||
else
|
||||
ippres = CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, IPPGray2BGRFunctor<Ipp32f>());
|
||||
}
|
||||
else if(dcn == 4)
|
||||
{
|
||||
if( depth == CV_8U )
|
||||
ippres = CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, IPPGray2BGRAFunctor<Ipp8u>());
|
||||
else if( depth == CV_16U )
|
||||
ippres = CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, IPPGray2BGRAFunctor<Ipp16u>());
|
||||
else
|
||||
ippres = CvtColorIPPLoop(src_data, src_step, dst_data, dst_step, width, height, IPPGray2BGRAFunctor<Ipp32f>());
|
||||
}
|
||||
if(ippres)
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
CV_CPU_DISPATCH(cvtGraytoBGR, (src_data, src_step, dst_data, dst_step, width, height, depth, dcn),
|
||||
CV_CPU_DISPATCH_MODES_ALL);
|
||||
}
|
||||
@@ -390,15 +124,6 @@ void cvtRGBAtoMultipliedRGBA(const uchar * src_data, size_t src_step,
|
||||
|
||||
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
|
||||
|
||||
CV_CPU_DISPATCH(cvtRGBAtoMultipliedRGBA, (src_data, src_step, dst_data, dst_step, width, height),
|
||||
CV_CPU_DISPATCH_MODES_ALL);
|
||||
}
|
||||
|
||||
@@ -139,11 +139,7 @@ struct RGB2RGB
|
||||
d = v_set<_Tp>::set(alphav);
|
||||
}
|
||||
if(bi == 2) {
|
||||
#if CV_SIMD_SCALABLE
|
||||
auto t = a; a = c; c = t; // swap(a, c);
|
||||
#else
|
||||
swap(a, c);
|
||||
#endif
|
||||
v_swap(a, c);
|
||||
}
|
||||
|
||||
if(dcn == 4)
|
||||
@@ -235,11 +231,7 @@ struct RGB5x52RGB
|
||||
r = v_pack(r0, r1);
|
||||
|
||||
if(bidx == 2) {
|
||||
#if CV_SIMD_SCALABLE
|
||||
auto t = r; r = b; b = t; // swap(b, r);
|
||||
#else
|
||||
swap(b, r);
|
||||
#endif
|
||||
v_swap(b, r);
|
||||
}
|
||||
if(dcn == 4)
|
||||
{
|
||||
@@ -318,11 +310,7 @@ struct RGB2RGB5x5
|
||||
v_load_deinterleave(src, b, g, r, a);
|
||||
}
|
||||
if(bidx == 2){
|
||||
#if CV_SIMD_SCALABLE
|
||||
auto t = r; r = b; b = t; // swap(b, r);
|
||||
#else
|
||||
swap(b, r);
|
||||
#endif
|
||||
v_swap(b, r);
|
||||
}
|
||||
|
||||
r = v_and(r, v7);
|
||||
@@ -1106,12 +1094,8 @@ void cvtBGRtoBGR(const uchar * src_data, size_t src_step,
|
||||
CV_INSTRUMENT_REGION();
|
||||
|
||||
int blueIdx = swapBlue ? 2 : 0;
|
||||
if( depth == CV_8U )
|
||||
CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, RGB2RGB<uchar>(scn, dcn, blueIdx));
|
||||
else if( depth == CV_16U )
|
||||
CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, RGB2RGB<ushort>(scn, dcn, blueIdx));
|
||||
else
|
||||
CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, RGB2RGB<float>(scn, dcn, blueIdx));
|
||||
CvtColorLoopDepth(src_data, src_step, dst_data, dst_step, width, height, depth,
|
||||
[&](auto t){ using T = decltype(t); return RGB2RGB<T>(scn, dcn, blueIdx); });
|
||||
}
|
||||
|
||||
// only 8u
|
||||
@@ -1145,12 +1129,8 @@ void cvtBGRtoGray(const uchar * src_data, size_t src_step,
|
||||
CV_INSTRUMENT_REGION();
|
||||
|
||||
int blueIdx = swapBlue ? 2 : 0;
|
||||
if( depth == CV_8U )
|
||||
CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, RGB2Gray<uchar>(scn, blueIdx, 0));
|
||||
else if( depth == CV_16U )
|
||||
CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, RGB2Gray<ushort>(scn, blueIdx, 0));
|
||||
else
|
||||
CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, RGB2Gray<float>(scn, blueIdx, 0));
|
||||
CvtColorLoopDepth(src_data, src_step, dst_data, dst_step, width, height, depth,
|
||||
[&](auto t){ using T = decltype(t); return RGB2Gray<T>(scn, blueIdx, 0); });
|
||||
}
|
||||
|
||||
// 8u, 16u, 32f
|
||||
@@ -1161,12 +1141,8 @@ void cvtGraytoBGR(const uchar * src_data, size_t src_step,
|
||||
{
|
||||
CV_INSTRUMENT_REGION();
|
||||
|
||||
if( depth == CV_8U )
|
||||
CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, Gray2RGB<uchar>(dcn));
|
||||
else if( depth == CV_16U )
|
||||
CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, Gray2RGB<ushort>(dcn));
|
||||
else
|
||||
CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, Gray2RGB<float>(dcn));
|
||||
CvtColorLoopDepth(src_data, src_step, dst_data, dst_step, width, height, depth,
|
||||
[&](auto t){ using T = decltype(t); return Gray2RGB<T>(dcn); });
|
||||
}
|
||||
|
||||
// only 8u
|
||||
|
||||
@@ -32,41 +32,6 @@ void cvtBGRtoYUV(const uchar * src_data, size_t src_step,
|
||||
|
||||
CALL_HAL(cvtBGRtoYUV, cv_hal_cvtBGRtoYUV, src_data, src_step, dst_data, dst_step, width, height, depth, scn, swapBlue, isCbCr);
|
||||
|
||||
#if defined(HAVE_IPP)
|
||||
#if !IPP_DISABLE_RGB_YUV
|
||||
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
|
||||
#endif
|
||||
|
||||
CV_CPU_DISPATCH(cvtBGRtoYUV, (src_data, src_step, dst_data, dst_step, width, height, depth, scn, swapBlue, isCbCr),
|
||||
CV_CPU_DISPATCH_MODES_ALL);
|
||||
}
|
||||
@@ -85,42 +50,6 @@ void cvtYUVtoBGR(const uchar * src_data, size_t src_step,
|
||||
|
||||
CALL_HAL(cvtYUVtoBGR, cv_hal_cvtYUVtoBGR, src_data, src_step, dst_data, dst_step, width, height, depth, dcn, swapBlue, isCbCr);
|
||||
|
||||
|
||||
#if defined(HAVE_IPP)
|
||||
#if !IPP_DISABLE_YUV_RGB
|
||||
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
|
||||
#endif
|
||||
|
||||
CV_CPU_DISPATCH(cvtYUVtoBGR, (src_data, src_step, dst_data, dst_step, width, height, depth, dcn, swapBlue, isCbCr),
|
||||
CV_CPU_DISPATCH_MODES_ALL);
|
||||
}
|
||||
@@ -488,13 +417,6 @@ void cvtColorYUV2Gray_420( InputArray _src, OutputArray _dst )
|
||||
{
|
||||
CvtHelper< Set<1>, Set<1>, Set<CV_8U>, FROM_YUV > h(_src, _dst, 1);
|
||||
|
||||
#ifdef HAVE_IPP
|
||||
#if IPP_VERSION_X100 >= 201700
|
||||
if (CV_INSTRUMENT_FUN_IPP(ippiCopy_8u_C1R_L, h.src.data, (IppSizeL)h.src.step, h.dst.data, (IppSizeL)h.dst.step,
|
||||
ippiSizeL(h.dstSz.width, h.dstSz.height)) >= 0)
|
||||
return;
|
||||
#endif
|
||||
#endif
|
||||
h.src(Range(0, h.dstSz.height), Range::all()).copyTo(h.dst);
|
||||
}
|
||||
|
||||
|
||||
@@ -53,15 +53,6 @@ void cvtOnePlaneBGRtoYUV(const uchar * src_data, size_t src_step,
|
||||
namespace {
|
||||
//constants for conversion from/to RGB and YUV, YCrCb according to BT.601
|
||||
|
||||
#if CV_SIMD_SCALABLE
|
||||
template <class T>
|
||||
static void swap(T&a, T&b) {
|
||||
T t = a;
|
||||
a = b;
|
||||
b = t;
|
||||
}
|
||||
#endif
|
||||
|
||||
//to YCbCr
|
||||
static const float YCBF = 0.564f; // == 1/2/(1-B2YF)
|
||||
static const float YCRF = 0.713f; // == 1/2/(1-R2YF)
|
||||
@@ -91,6 +82,14 @@ static const int CB2GI = -5636;
|
||||
static const int CR2GI = -11698;
|
||||
static const int CR2RI = 22987;
|
||||
|
||||
// select YCrCb (crcb) or YUV (yuv) coefficients into coeffs; size N deduced
|
||||
template<typename CT, int N>
|
||||
static inline void selectYuvCoeffs(CT (&coeffs)[N], bool isCrCb, const CT (&crcb)[N], const CT (&yuv)[N])
|
||||
{
|
||||
for(int i = 0; i < N; i++)
|
||||
coeffs[i] = isCrCb ? crcb[i] : yuv[i];
|
||||
}
|
||||
|
||||
///////////////////////////////////// RGB <-> YCrCb //////////////////////////////////////
|
||||
|
||||
template<typename _Tp> struct RGB2YCrCb_f
|
||||
@@ -102,10 +101,7 @@ template<typename _Tp> struct RGB2YCrCb_f
|
||||
{
|
||||
static const float coeffs_crb[] = { R2YF, G2YF, B2YF, YCRF, YCBF };
|
||||
static const float coeffs_yuv[] = { R2YF, G2YF, B2YF, R2VF, B2UF };
|
||||
for(int i = 0; i < 5; i++)
|
||||
{
|
||||
coeffs[i] = isCrCb ? coeffs_crb[i] : coeffs_yuv[i];
|
||||
}
|
||||
selectYuvCoeffs(coeffs, isCrCb, coeffs_crb, coeffs_yuv);
|
||||
if(blueIdx == 0)
|
||||
std::swap(coeffs[0], coeffs[2]);
|
||||
}
|
||||
@@ -140,10 +136,7 @@ struct RGB2YCrCb_f<float>
|
||||
{
|
||||
static const float coeffs_crb[] = { R2YF, G2YF, B2YF, YCRF, YCBF };
|
||||
static const float coeffs_yuv[] = { R2YF, G2YF, B2YF, R2VF, B2UF };
|
||||
for(int i = 0; i < 5; i++)
|
||||
{
|
||||
coeffs[i] = isCrCb ? coeffs_crb[i] : coeffs_yuv[i];
|
||||
}
|
||||
selectYuvCoeffs(coeffs, isCrCb, coeffs_crb, coeffs_yuv);
|
||||
if(blueIdx == 0)
|
||||
std::swap(coeffs[0], coeffs[2]);
|
||||
}
|
||||
@@ -178,7 +171,7 @@ struct RGB2YCrCb_f<float>
|
||||
y = v_fma(b, vc0, v_fma(g, vc1, v_mul(r, vc2)));
|
||||
|
||||
if(bidx)
|
||||
swap(r, b);
|
||||
v_swap(r, b);
|
||||
|
||||
cr = v_fma(v_sub(r, y), vc3, vdelta);
|
||||
cb = v_fma(v_sub(b, y), vc4, vdelta);
|
||||
@@ -222,10 +215,7 @@ template<typename _Tp> struct RGB2YCrCb_i
|
||||
static const int coeffs_crb[] = { R2Y, G2Y, B2Y, YCRI, YCBI };
|
||||
static const int coeffs_yuv[] = { R2Y, G2Y, B2Y, R2VI, B2UI };
|
||||
|
||||
for(int i = 0; i < 5; i++)
|
||||
{
|
||||
coeffs[i] = isCrCb ? coeffs_crb[i] : coeffs_yuv[i];
|
||||
}
|
||||
selectYuvCoeffs(coeffs, isCrCb, coeffs_crb, coeffs_yuv);
|
||||
if(blueIdx==0) std::swap(coeffs[0], coeffs[2]);
|
||||
}
|
||||
void operator()(const _Tp* src, _Tp* dst, int n) const
|
||||
@@ -264,10 +254,7 @@ struct RGB2YCrCb_i<ushort>
|
||||
static const int coeffs_crb[] = { R2Y, G2Y, B2Y, YCRI, YCBI };
|
||||
static const int coeffs_yuv[] = { R2Y, G2Y, B2Y, R2VI, B2UI };
|
||||
|
||||
for(int i = 0; i < 5; i++)
|
||||
{
|
||||
coeffs[i] = isCrCb ? coeffs_crb[i] : coeffs_yuv[i];
|
||||
}
|
||||
selectYuvCoeffs(coeffs, isCrCb, coeffs_crb, coeffs_yuv);
|
||||
if(blueIdx==0)
|
||||
std::swap(coeffs[0], coeffs[2]);
|
||||
}
|
||||
@@ -336,7 +323,7 @@ struct RGB2YCrCb_i<ushort>
|
||||
y = v_reinterpret_as_u16(v_add_wrap(v_pack(ssy0, ssy1), fixmul));
|
||||
|
||||
if(bidx)
|
||||
swap(r, b);
|
||||
v_swap(r, b);
|
||||
|
||||
// (r-Y) and (b-Y) don't fit into int16 or uint16 range
|
||||
v_uint32 r0, r1, b0, b1;
|
||||
@@ -405,10 +392,7 @@ struct RGB2YCrCb_i<uchar>
|
||||
{
|
||||
static const int coeffs_crb[] = { R2Y, G2Y, B2Y, YCRI, YCBI };
|
||||
static const int coeffs_yuv[] = { R2Y, G2Y, B2Y, R2VI, B2UI };
|
||||
for(int i = 0; i < 5; i++)
|
||||
{
|
||||
coeffs[i] = isCrCb ? coeffs_crb[i] : coeffs_yuv[i];
|
||||
}
|
||||
selectYuvCoeffs(coeffs, isCrCb, coeffs_crb, coeffs_yuv);
|
||||
if (blueIdx==0)
|
||||
std::swap(coeffs[0], coeffs[2]);
|
||||
}
|
||||
@@ -495,7 +479,7 @@ struct RGB2YCrCb_i<uchar>
|
||||
|
||||
if(bidx)
|
||||
{
|
||||
swap(sr0, sb0); swap(sr1, sb1);
|
||||
v_swap(sr0, sb0); v_swap(sr1, sb1);
|
||||
}
|
||||
|
||||
v_int32 cr00, cr01, cr10, cr11;
|
||||
@@ -579,10 +563,7 @@ template<typename _Tp> struct YCrCb2RGB_f
|
||||
{
|
||||
static const float coeffs_cbr[] = {CR2RF, CR2GF, CB2GF, CB2BF};
|
||||
static const float coeffs_yuv[] = { V2RF, V2GF, U2GF, U2BF};
|
||||
for(int i = 0; i < 4; i++)
|
||||
{
|
||||
coeffs[i] = isCrCb ? coeffs_cbr[i] : coeffs_yuv[i];
|
||||
}
|
||||
selectYuvCoeffs(coeffs, isCrCb, coeffs_cbr, coeffs_yuv);
|
||||
}
|
||||
void operator()(const _Tp* src, _Tp* dst, int n) const
|
||||
{
|
||||
@@ -622,10 +603,7 @@ struct YCrCb2RGB_f<float>
|
||||
{
|
||||
static const float coeffs_cbr[] = {CR2RF, CR2GF, CB2GF, CB2BF};
|
||||
static const float coeffs_yuv[] = { V2RF, V2GF, U2GF, U2BF};
|
||||
for(int i = 0; i < 4; i++)
|
||||
{
|
||||
coeffs[i] = isCrCb ? coeffs_cbr[i] : coeffs_yuv[i];
|
||||
}
|
||||
selectYuvCoeffs(coeffs, isCrCb, coeffs_cbr, coeffs_yuv);
|
||||
}
|
||||
|
||||
void operator()(const float* src, float* dst, int n) const
|
||||
@@ -659,7 +637,7 @@ struct YCrCb2RGB_f<float>
|
||||
r = v_fma(cr, vc0, y);
|
||||
|
||||
if(bidx)
|
||||
swap(r, b);
|
||||
v_swap(r, b);
|
||||
|
||||
if(dcn == 3)
|
||||
v_store_interleave(dst, b, g, r);
|
||||
@@ -699,10 +677,7 @@ template<typename _Tp> struct YCrCb2RGB_i
|
||||
{
|
||||
static const int coeffs_crb[] = { CR2RI, CR2GI, CB2GI, CB2BI};
|
||||
static const int coeffs_yuv[] = { V2RI, V2GI, U2GI, U2BI };
|
||||
for(int i = 0; i < 4; i++)
|
||||
{
|
||||
coeffs[i] = isCrCb ? coeffs_crb[i] : coeffs_yuv[i];
|
||||
}
|
||||
selectYuvCoeffs(coeffs, isCrCb, coeffs_crb, coeffs_yuv);
|
||||
}
|
||||
|
||||
void operator()(const _Tp* src, _Tp* dst, int n) const
|
||||
@@ -746,10 +721,7 @@ struct YCrCb2RGB_i<uchar>
|
||||
{
|
||||
static const int coeffs_crb[] = { CR2RI, CR2GI, CB2GI, CB2BI};
|
||||
static const int coeffs_yuv[] = { V2RI, V2GI, U2GI, U2BI };
|
||||
for(int i = 0; i < 4; i++)
|
||||
{
|
||||
coeffs[i] = isCrCb ? coeffs_crb[i] : coeffs_yuv[i];
|
||||
}
|
||||
selectYuvCoeffs(coeffs, isCrCb, coeffs_crb, coeffs_yuv);
|
||||
}
|
||||
|
||||
void operator()(const uchar* src, uchar* dst, int n) const
|
||||
@@ -849,7 +821,7 @@ struct YCrCb2RGB_i<uchar>
|
||||
r = v_pack_u(r0, r1);
|
||||
|
||||
if(bidx)
|
||||
swap(r, b);
|
||||
v_swap(r, b);
|
||||
|
||||
if(dcn == 3)
|
||||
{
|
||||
@@ -897,10 +869,7 @@ struct YCrCb2RGB_i<ushort>
|
||||
{
|
||||
static const int coeffs_crb[] = { CR2RI, CR2GI, CB2GI, CB2BI};
|
||||
static const int coeffs_yuv[] = { V2RI, V2GI, U2GI, U2BI };
|
||||
for(int i = 0; i < 4; i++)
|
||||
{
|
||||
coeffs[i] = isCrCb ? coeffs_crb[i] : coeffs_yuv[i];
|
||||
}
|
||||
selectYuvCoeffs(coeffs, isCrCb, coeffs_crb, coeffs_yuv);
|
||||
}
|
||||
|
||||
void operator()(const ushort* src, ushort* dst, int n) const
|
||||
@@ -976,7 +945,7 @@ struct YCrCb2RGB_i<ushort>
|
||||
r = v_pack_u(r0, r1);
|
||||
|
||||
if(bidx)
|
||||
swap(r, b);
|
||||
v_swap(r, b);
|
||||
|
||||
if(dcn == 3)
|
||||
{
|
||||
@@ -1191,6 +1160,74 @@ static inline void cvtYuv42xxp2RGB8(const uchar u, const uchar v,
|
||||
}
|
||||
}
|
||||
|
||||
#if (CV_SIMD || CV_SIMD_SCALABLE)
|
||||
// shared SIMD body for YUV420 sp/p -> RGB: u,v + 4 luma vectors -> two interleaved RGB rows
|
||||
template<int bIdx, int dcn>
|
||||
static CV_ALWAYS_INLINE void storeYUV420block(const v_uint8& u, const v_uint8& v,
|
||||
const v_uint8& vy0, const v_uint8& vy1,
|
||||
const v_uint8& vy2, const v_uint8& vy3,
|
||||
const v_uint8& a, int vsize, uchar* row1, uchar* row2)
|
||||
{
|
||||
v_int32 ruv0, ruv1, ruv2, ruv3,
|
||||
guv0, guv1, guv2, guv3,
|
||||
buv0, buv1, buv2, buv3;
|
||||
uvToRGBuv(u, v,
|
||||
ruv0, ruv1, ruv2, ruv3,
|
||||
guv0, guv1, guv2, guv3,
|
||||
buv0, buv1, buv2, buv3);
|
||||
|
||||
v_uint8 r0, r1, r2, r3, g0, g1, g2, g3, b0, b1, b2, b3;
|
||||
|
||||
auto call_yRGBuvToRGBA = [&](const v_uint8& vy, v_uint8& r, v_uint8& g, v_uint8& b) {
|
||||
yRGBuvToRGBA(vy,
|
||||
ruv0, ruv1, ruv2, ruv3,
|
||||
guv0, guv1, guv2, guv3,
|
||||
buv0, buv1, buv2, buv3,
|
||||
r, g, b);
|
||||
};
|
||||
call_yRGBuvToRGBA(vy0, r0, g0, b0);
|
||||
call_yRGBuvToRGBA(vy1, r1, g1, b1);
|
||||
call_yRGBuvToRGBA(vy2, r2, g2, b2);
|
||||
call_yRGBuvToRGBA(vy3, r3, g3, b3);
|
||||
|
||||
if(bIdx)
|
||||
{
|
||||
v_swap(r0, b0);
|
||||
v_swap(r1, b1);
|
||||
v_swap(r2, b2);
|
||||
v_swap(r3, b3);
|
||||
}
|
||||
|
||||
// [r0...], [r1...] => [r0, r1, r0, r1...], [r0, r1, r0, r1...]
|
||||
v_uint8 r0_0, r0_1, r1_0, r1_1;
|
||||
v_zip(r0, r1, r0_0, r0_1);
|
||||
v_zip(r2, r3, r1_0, r1_1);
|
||||
v_uint8 g0_0, g0_1, g1_0, g1_1;
|
||||
v_zip(g0, g1, g0_0, g0_1);
|
||||
v_zip(g2, g3, g1_0, g1_1);
|
||||
v_uint8 b0_0, b0_1, b1_0, b1_1;
|
||||
v_zip(b0, b1, b0_0, b0_1);
|
||||
v_zip(b2, b3, b1_0, b1_1);
|
||||
|
||||
if(dcn == 4)
|
||||
{
|
||||
v_store_interleave(row1 + 0*vsize, b0_0, g0_0, r0_0, a);
|
||||
v_store_interleave(row1 + 4*vsize, b0_1, g0_1, r0_1, a);
|
||||
|
||||
v_store_interleave(row2 + 0*vsize, b1_0, g1_0, r1_0, a);
|
||||
v_store_interleave(row2 + 4*vsize, b1_1, g1_1, r1_1, a);
|
||||
}
|
||||
else //dcn == 3
|
||||
{
|
||||
v_store_interleave(row1 + 0*vsize, b0_0, g0_0, r0_0);
|
||||
v_store_interleave(row1 + 3*vsize, b0_1, g0_1, r0_1);
|
||||
|
||||
v_store_interleave(row2 + 0*vsize, b1_0, g1_0, r1_0);
|
||||
v_store_interleave(row2 + 3*vsize, b1_1, g1_1, r1_1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// bIdx is 0 or 2, uIdx is 0 or 1, dcn is 3 or 4
|
||||
template<int bIdx, int uIdx, int dcn>
|
||||
struct YUV420sp2RGB8Invoker : ParallelLoopBody
|
||||
@@ -1233,70 +1270,14 @@ struct YUV420sp2RGB8Invoker : ParallelLoopBody
|
||||
|
||||
if(uIdx)
|
||||
{
|
||||
swap(u, v);
|
||||
v_swap(u, v);
|
||||
}
|
||||
|
||||
v_uint8 vy0, vy1, vy2, vy3;
|
||||
v_load_deinterleave(y1 + i, vy0, vy1);
|
||||
v_load_deinterleave(y2 + i, vy2, vy3);
|
||||
|
||||
v_int32 ruv0, ruv1, ruv2, ruv3,
|
||||
guv0, guv1, guv2, guv3,
|
||||
buv0, buv1, buv2, buv3;
|
||||
uvToRGBuv(u, v,
|
||||
ruv0, ruv1, ruv2, ruv3,
|
||||
guv0, guv1, guv2, guv3,
|
||||
buv0, buv1, buv2, buv3);
|
||||
|
||||
v_uint8 r0, r1, r2, r3, g0, g1, g2, g3, b0, b1, b2, b3;
|
||||
|
||||
auto call_yRGBuvToRGBA = [&](const v_uint8& vy, v_uint8& r, v_uint8& g, v_uint8& b) {
|
||||
yRGBuvToRGBA(vy,
|
||||
ruv0, ruv1, ruv2, ruv3,
|
||||
guv0, guv1, guv2, guv3,
|
||||
buv0, buv1, buv2, buv3,
|
||||
r, g, b);
|
||||
};
|
||||
call_yRGBuvToRGBA(vy0, r0, g0, b0);
|
||||
call_yRGBuvToRGBA(vy1, r1, g1, b1);
|
||||
call_yRGBuvToRGBA(vy2, r2, g2, b2);
|
||||
call_yRGBuvToRGBA(vy3, r3, g3, b3);
|
||||
|
||||
if(bIdx)
|
||||
{
|
||||
swap(r0, b0);
|
||||
swap(r1, b1);
|
||||
swap(r2, b2);
|
||||
swap(r3, b3);
|
||||
}
|
||||
|
||||
// [r0...], [r1...] => [r0, r1, r0, r1...], [r0, r1, r0, r1...]
|
||||
v_uint8 r0_0, r0_1, r1_0, r1_1;
|
||||
v_zip(r0, r1, r0_0, r0_1);
|
||||
v_zip(r2, r3, r1_0, r1_1);
|
||||
v_uint8 g0_0, g0_1, g1_0, g1_1;
|
||||
v_zip(g0, g1, g0_0, g0_1);
|
||||
v_zip(g2, g3, g1_0, g1_1);
|
||||
v_uint8 b0_0, b0_1, b1_0, b1_1;
|
||||
v_zip(b0, b1, b0_0, b0_1);
|
||||
v_zip(b2, b3, b1_0, b1_1);
|
||||
|
||||
if(dcn == 4)
|
||||
{
|
||||
v_store_interleave(row1 + 0*vsize, b0_0, g0_0, r0_0, a);
|
||||
v_store_interleave(row1 + 4*vsize, b0_1, g0_1, r0_1, a);
|
||||
|
||||
v_store_interleave(row2 + 0*vsize, b1_0, g1_0, r1_0, a);
|
||||
v_store_interleave(row2 + 4*vsize, b1_1, g1_1, r1_1, a);
|
||||
}
|
||||
else //dcn == 3
|
||||
{
|
||||
v_store_interleave(row1 + 0*vsize, b0_0, g0_0, r0_0);
|
||||
v_store_interleave(row1 + 3*vsize, b0_1, g0_1, r0_1);
|
||||
|
||||
v_store_interleave(row2 + 0*vsize, b1_0, g1_0, r1_0);
|
||||
v_store_interleave(row2 + 3*vsize, b1_1, g1_1, r1_1);
|
||||
}
|
||||
storeYUV420block<bIdx, dcn>(u, v, vy0, vy1, vy2, vy3, a, vsize, row1, row2);
|
||||
}
|
||||
vx_cleanup();
|
||||
#endif
|
||||
@@ -1368,63 +1349,7 @@ struct YUV420p2RGB8Invoker : ParallelLoopBody
|
||||
v_load_deinterleave(y1 + 2*i, vy0, vy1);
|
||||
v_load_deinterleave(y2 + 2*i, vy2, vy3);
|
||||
|
||||
v_int32 ruv0, ruv1, ruv2, ruv3,
|
||||
guv0, guv1, guv2, guv3,
|
||||
buv0, buv1, buv2, buv3;
|
||||
uvToRGBuv(u, v,
|
||||
ruv0, ruv1, ruv2, ruv3,
|
||||
guv0, guv1, guv2, guv3,
|
||||
buv0, buv1, buv2, buv3);
|
||||
|
||||
v_uint8 r0, r1, r2, r3, g0, g1, g2, g3, b0, b1, b2, b3;
|
||||
|
||||
auto call_yRGBuvToRGBA = [&](const v_uint8& vy, v_uint8& r, v_uint8& g, v_uint8& b) {
|
||||
yRGBuvToRGBA(vy,
|
||||
ruv0, ruv1, ruv2, ruv3,
|
||||
guv0, guv1, guv2, guv3,
|
||||
buv0, buv1, buv2, buv3,
|
||||
r, g, b);
|
||||
};
|
||||
call_yRGBuvToRGBA(vy0, r0, g0, b0);
|
||||
call_yRGBuvToRGBA(vy1, r1, g1, b1);
|
||||
call_yRGBuvToRGBA(vy2, r2, g2, b2);
|
||||
call_yRGBuvToRGBA(vy3, r3, g3, b3);
|
||||
|
||||
if(bIdx)
|
||||
{
|
||||
swap(r0, b0);
|
||||
swap(r1, b1);
|
||||
swap(r2, b2);
|
||||
swap(r3, b3);
|
||||
}
|
||||
|
||||
// [r0...], [r1...] => [r0, r1, r0, r1...], [r0, r1, r0, r1...]
|
||||
v_uint8 r0_0, r0_1, r1_0, r1_1;
|
||||
v_zip(r0, r1, r0_0, r0_1);
|
||||
v_zip(r2, r3, r1_0, r1_1);
|
||||
v_uint8 g0_0, g0_1, g1_0, g1_1;
|
||||
v_zip(g0, g1, g0_0, g0_1);
|
||||
v_zip(g2, g3, g1_0, g1_1);
|
||||
v_uint8 b0_0, b0_1, b1_0, b1_1;
|
||||
v_zip(b0, b1, b0_0, b0_1);
|
||||
v_zip(b2, b3, b1_0, b1_1);
|
||||
|
||||
if(dcn == 4)
|
||||
{
|
||||
v_store_interleave(row1 + 0*vsize, b0_0, g0_0, r0_0, a);
|
||||
v_store_interleave(row1 + 4*vsize, b0_1, g0_1, r0_1, a);
|
||||
|
||||
v_store_interleave(row2 + 0*vsize, b1_0, g1_0, r1_0, a);
|
||||
v_store_interleave(row2 + 4*vsize, b1_1, g1_1, r1_1, a);
|
||||
}
|
||||
else //dcn == 3
|
||||
{
|
||||
v_store_interleave(row1 + 0*vsize, b0_0, g0_0, r0_0);
|
||||
v_store_interleave(row1 + 3*vsize, b0_1, g0_1, r0_1);
|
||||
|
||||
v_store_interleave(row2 + 0*vsize, b1_0, g1_0, r1_0);
|
||||
v_store_interleave(row2 + 3*vsize, b1_1, g1_1, r1_1);
|
||||
}
|
||||
storeYUV420block<bIdx, dcn>(u, v, vy0, vy1, vy2, vy3, a, vsize, row1, row2);
|
||||
}
|
||||
vx_cleanup();
|
||||
#endif
|
||||
@@ -1632,7 +1557,7 @@ struct RGB8toYUV420pInvoker: public ParallelLoopBody
|
||||
|
||||
if(swapBlue)
|
||||
{
|
||||
swap(b0, r0); swap(b1, r1);
|
||||
v_swap(b0, r0); v_swap(b1, r1);
|
||||
}
|
||||
|
||||
v_uint8 y0, y1;
|
||||
@@ -1650,7 +1575,7 @@ struct RGB8toYUV420pInvoker: public ParallelLoopBody
|
||||
|
||||
if(swapUV)
|
||||
{
|
||||
swap(u, v);
|
||||
v_swap(u, v);
|
||||
}
|
||||
|
||||
if(interleave)
|
||||
@@ -1680,7 +1605,7 @@ struct RGB8toYUV420pInvoker: public ParallelLoopBody
|
||||
|
||||
if(swapBlue)
|
||||
{
|
||||
swap(b0, r0); swap(b1, r1);
|
||||
v_swap(b0, r0); v_swap(b1, r1);
|
||||
}
|
||||
|
||||
uchar y0 = rgbToY42x(r0, g0, b0);
|
||||
@@ -1695,7 +1620,7 @@ struct RGB8toYUV420pInvoker: public ParallelLoopBody
|
||||
rgbToUV42x(r0, g0, b0, uu, vv);
|
||||
if(swapUV)
|
||||
{
|
||||
swap(uu, vv);
|
||||
v_swap(uu, vv);
|
||||
}
|
||||
|
||||
if(interleave)
|
||||
@@ -1776,7 +1701,7 @@ struct YUV422toRGB8Invoker : ParallelLoopBody
|
||||
v_load_deinterleave(yuv_src + i, vy0, u, vy1, v);
|
||||
if(uIdx == 1) // YVYU
|
||||
{
|
||||
swap(u, v);
|
||||
v_swap(u, v);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1804,8 +1729,8 @@ struct YUV422toRGB8Invoker : ParallelLoopBody
|
||||
|
||||
if(bIdx)
|
||||
{
|
||||
swap(r0, b0);
|
||||
swap(r1, b1);
|
||||
v_swap(r0, b0);
|
||||
v_swap(r1, b1);
|
||||
}
|
||||
|
||||
// [r0...], [r1...] => [r0, r1, r0, r1...], [r0, r1, r0, r1...]
|
||||
@@ -1899,6 +1824,77 @@ static inline void RGB2UV(const uchar r1, const uchar g1, const uchar b1,
|
||||
v = saturate_cast<uchar>(((1 << (RGB2YUV422_SHIFT-1)) + v_) >> RGB2YUV422_SHIFT);
|
||||
}
|
||||
|
||||
#if (CV_SIMD || CV_SIMD_SCALABLE)
|
||||
// SIMD RGB2Y: v_dotprod (pmaddwd) keeps the multiply in 16-bit, avoiding emulated 32-bit mul on pre-SSE4.1
|
||||
static inline v_uint8 v_RGB2Y(const v_uint8& r, const v_uint8& g, const v_uint8& b)
|
||||
{
|
||||
v_int16 crg, cb, dummy;
|
||||
v_zip(vx_setall_s16((short)R2Y422), vx_setall_s16((short)G2Y422), crg, dummy);
|
||||
v_zip(vx_setall_s16((short)B2Y422), vx_setall_s16(0), cb, dummy);
|
||||
v_int32 vbias = vx_setall_s32((1 << RGB2YUV422_SHIFT) * 16 + (1 << (RGB2YUV422_SHIFT - 1)));
|
||||
v_int16 vzero = vx_setzero_s16();
|
||||
|
||||
v_uint16 r0, r1, g0, g1, b0, b1;
|
||||
v_expand(r, r0, r1); v_expand(g, g0, g1); v_expand(b, b0, b1);
|
||||
v_int16 sr0 = v_reinterpret_as_s16(r0), sr1 = v_reinterpret_as_s16(r1);
|
||||
v_int16 sg0 = v_reinterpret_as_s16(g0), sg1 = v_reinterpret_as_s16(g1);
|
||||
v_int16 sb0 = v_reinterpret_as_s16(b0), sb1 = v_reinterpret_as_s16(b1);
|
||||
|
||||
v_int16 rg00, rg01, rg10, rg11, bz00, bz01, bz10, bz11;
|
||||
v_zip(sr0, sg0, rg00, rg01); v_zip(sr1, sg1, rg10, rg11);
|
||||
v_zip(sb0, vzero, bz00, bz01); v_zip(sb1, vzero, bz10, bz11);
|
||||
|
||||
v_uint32 y00, y01, y10, y11;
|
||||
y00 = v_shr<RGB2YUV422_SHIFT>(v_reinterpret_as_u32(v_add(v_add(v_dotprod(rg00, crg), v_dotprod(bz00, cb)), vbias)));
|
||||
y01 = v_shr<RGB2YUV422_SHIFT>(v_reinterpret_as_u32(v_add(v_add(v_dotprod(rg01, crg), v_dotprod(bz01, cb)), vbias)));
|
||||
y10 = v_shr<RGB2YUV422_SHIFT>(v_reinterpret_as_u32(v_add(v_add(v_dotprod(rg10, crg), v_dotprod(bz10, cb)), vbias)));
|
||||
y11 = v_shr<RGB2YUV422_SHIFT>(v_reinterpret_as_u32(v_add(v_add(v_dotprod(rg11, crg), v_dotprod(bz11, cb)), vbias)));
|
||||
|
||||
return v_pack(v_pack(y00, y01), v_pack(y10, y11));
|
||||
}
|
||||
|
||||
// SIMD RGB2UV (same v_dotprod approach); (r0,g0,b0) is the first pixel of each pair, (r1,g1,b1) the second
|
||||
static inline void v_RGB2UV(const v_uint8& r0, const v_uint8& g0, const v_uint8& b0,
|
||||
const v_uint8& r1, const v_uint8& g1, const v_uint8& b1,
|
||||
v_uint8& u, v_uint8& v)
|
||||
{
|
||||
v_int16 cu_rg, cu_b, cv_rg, cv_b, dummy;
|
||||
v_zip(vx_setall_s16((short)R2U422), vx_setall_s16((short)G2U422), cu_rg, dummy);
|
||||
v_zip(vx_setall_s16((short)B2U422), vx_setall_s16(0), cu_b, dummy);
|
||||
v_zip(vx_setall_s16((short)B2U422), vx_setall_s16((short)G2V422), cv_rg, dummy);
|
||||
v_zip(vx_setall_s16((short)B2V422), vx_setall_s16(0), cv_b, dummy);
|
||||
v_int32 vbias = vx_setall_s32((1 << (RGB2YUV422_SHIFT - 1)) * 256 + (1 << (RGB2YUV422_SHIFT - 1)));
|
||||
v_int16 vzero = vx_setzero_s16();
|
||||
|
||||
v_uint16 r0a, r0b, r1a, r1b, g0a, g0b, g1a, g1b, b0a, b0b, b1a, b1b;
|
||||
v_expand(r0, r0a, r0b); v_expand(r1, r1a, r1b);
|
||||
v_expand(g0, g0a, g0b); v_expand(g1, g1a, g1b);
|
||||
v_expand(b0, b0a, b0b); v_expand(b1, b1a, b1b);
|
||||
|
||||
// per-pair sums sr=r0+r1, sg=g0+g1, sb=b0+b1 (max 510, fits s16)
|
||||
v_int16 sr0 = v_reinterpret_as_s16(v_add(r0a, r1a)), sr1 = v_reinterpret_as_s16(v_add(r0b, r1b));
|
||||
v_int16 sg0 = v_reinterpret_as_s16(v_add(g0a, g1a)), sg1 = v_reinterpret_as_s16(v_add(g0b, g1b));
|
||||
v_int16 sb0 = v_reinterpret_as_s16(v_add(b0a, b1a)), sb1 = v_reinterpret_as_s16(v_add(b0b, b1b));
|
||||
|
||||
v_int16 rg00, rg01, rg10, rg11, bz00, bz01, bz10, bz11;
|
||||
v_zip(sr0, sg0, rg00, rg01); v_zip(sr1, sg1, rg10, rg11);
|
||||
v_zip(sb0, vzero, bz00, bz01); v_zip(sb1, vzero, bz10, bz11);
|
||||
|
||||
v_int32 uq00, uq01, uq10, uq11, vq00, vq01, vq10, vq11;
|
||||
uq00 = v_shr<RGB2YUV422_SHIFT>(v_add(v_add(v_dotprod(rg00, cu_rg), v_dotprod(bz00, cu_b)), vbias));
|
||||
uq01 = v_shr<RGB2YUV422_SHIFT>(v_add(v_add(v_dotprod(rg01, cu_rg), v_dotprod(bz01, cu_b)), vbias));
|
||||
uq10 = v_shr<RGB2YUV422_SHIFT>(v_add(v_add(v_dotprod(rg10, cu_rg), v_dotprod(bz10, cu_b)), vbias));
|
||||
uq11 = v_shr<RGB2YUV422_SHIFT>(v_add(v_add(v_dotprod(rg11, cu_rg), v_dotprod(bz11, cu_b)), vbias));
|
||||
vq00 = v_shr<RGB2YUV422_SHIFT>(v_add(v_add(v_dotprod(rg00, cv_rg), v_dotprod(bz00, cv_b)), vbias));
|
||||
vq01 = v_shr<RGB2YUV422_SHIFT>(v_add(v_add(v_dotprod(rg01, cv_rg), v_dotprod(bz01, cv_b)), vbias));
|
||||
vq10 = v_shr<RGB2YUV422_SHIFT>(v_add(v_add(v_dotprod(rg10, cv_rg), v_dotprod(bz10, cv_b)), vbias));
|
||||
vq11 = v_shr<RGB2YUV422_SHIFT>(v_add(v_add(v_dotprod(rg11, cv_rg), v_dotprod(bz11, cv_b)), vbias));
|
||||
|
||||
u = v_pack_u(v_pack(uq00, uq01), v_pack(uq10, uq11));
|
||||
v = v_pack_u(v_pack(vq00, vq01), v_pack(vq10, vq11));
|
||||
}
|
||||
#endif
|
||||
|
||||
template<int yidx, int uidx, int vidx>
|
||||
static inline void cvtRGB82Yuv422(const uchar r1, const uchar g1, const uchar b1,
|
||||
const uchar r2, const uchar g2, const uchar b2,
|
||||
@@ -1946,6 +1942,49 @@ struct RGB8toYUV422Invoker : ParallelLoopBody
|
||||
{
|
||||
uchar* row = dst_data + (dst_step) * j;
|
||||
int i = 0;
|
||||
#if (CV_SIMD || CV_SIMD_SCALABLE)
|
||||
const int vsize = VTraits<v_uint8>::vlanes();
|
||||
v_uint16 lowByte = vx_setall_u16(0x00ff);
|
||||
// process 2*vsize source pixels -> vsize pairs -> 4*vsize output bytes
|
||||
for( ; i <= scn*width - 2*vsize*scn; i += 2*vsize*scn, row += 4*vsize )
|
||||
{
|
||||
v_uint8 c0lo, glo, c2lo, alo, c0hi, ghi, c2hi, ahi;
|
||||
if(scn == 4)
|
||||
{
|
||||
v_load_deinterleave(rgb_src + i + 0*vsize*scn, c0lo, glo, c2lo, alo);
|
||||
v_load_deinterleave(rgb_src + i + 1*vsize*scn, c0hi, ghi, c2hi, ahi);
|
||||
}
|
||||
else // scn == 3
|
||||
{
|
||||
v_load_deinterleave(rgb_src + i + 0*vsize*scn, c0lo, glo, c2lo);
|
||||
v_load_deinterleave(rgb_src + i + 1*vsize*scn, c0hi, ghi, c2hi);
|
||||
}
|
||||
|
||||
v_uint8 rlo = (bIdx == 0) ? c2lo : c0lo, blo = (bIdx == 0) ? c0lo : c2lo;
|
||||
v_uint8 rhi = (bIdx == 0) ? c2hi : c0hi, bhi = (bIdx == 0) ? c0hi : c2hi;
|
||||
|
||||
// split each chunk into even/odd pixels (the two members of every pair)
|
||||
v_uint8 rEven = v_pack(v_and(v_reinterpret_as_u16(rlo), lowByte), v_and(v_reinterpret_as_u16(rhi), lowByte));
|
||||
v_uint8 gEven = v_pack(v_and(v_reinterpret_as_u16(glo), lowByte), v_and(v_reinterpret_as_u16(ghi), lowByte));
|
||||
v_uint8 bEven = v_pack(v_and(v_reinterpret_as_u16(blo), lowByte), v_and(v_reinterpret_as_u16(bhi), lowByte));
|
||||
v_uint8 rOdd = v_pack(v_shr<8>(v_reinterpret_as_u16(rlo)), v_shr<8>(v_reinterpret_as_u16(rhi)));
|
||||
v_uint8 gOdd = v_pack(v_shr<8>(v_reinterpret_as_u16(glo)), v_shr<8>(v_reinterpret_as_u16(ghi)));
|
||||
v_uint8 bOdd = v_pack(v_shr<8>(v_reinterpret_as_u16(blo)), v_shr<8>(v_reinterpret_as_u16(bhi)));
|
||||
|
||||
v_uint8 yEven = v_RGB2Y(rEven, gEven, bEven);
|
||||
v_uint8 yOdd = v_RGB2Y(rOdd, gOdd, bOdd);
|
||||
v_uint8 u, v;
|
||||
v_RGB2UV(rEven, gEven, bEven, rOdd, gOdd, bOdd, u, v);
|
||||
|
||||
if(yIdx == 1) // UYVY
|
||||
v_store_interleave(row, u, yEven, v, yOdd);
|
||||
else if(uIdx == 0) // YUYV
|
||||
v_store_interleave(row, yEven, u, yOdd, v);
|
||||
else // YVYU
|
||||
v_store_interleave(row, yEven, v, yOdd, u);
|
||||
}
|
||||
vx_cleanup();
|
||||
#endif
|
||||
for (; i < scn * width; i += (scn << 1), row += 4)
|
||||
{
|
||||
const uchar r1 = rgb_src[i+ridx], g1 = rgb_src[i+1], b1 = rgb_src[i+bIdx];
|
||||
@@ -1981,12 +2020,12 @@ void cvtBGRtoYUV(const uchar * src_data, size_t src_step,
|
||||
CV_INSTRUMENT_REGION();
|
||||
|
||||
int blueIdx = swapBlue ? 2 : 0;
|
||||
if( depth == CV_8U )
|
||||
CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, RGB2YCrCb_i<uchar>(scn, blueIdx, isCbCr));
|
||||
else if( depth == CV_16U )
|
||||
CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, RGB2YCrCb_i<ushort>(scn, blueIdx, isCbCr));
|
||||
else
|
||||
CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, RGB2YCrCb_f<float>(scn, blueIdx, isCbCr));
|
||||
CvtColorLoopDepth(src_data, src_step, dst_data, dst_step, width, height, depth,
|
||||
[&](auto t){ using T = decltype(t);
|
||||
if constexpr (std::is_same<T, float>::value)
|
||||
return RGB2YCrCb_f<float>(scn, blueIdx, isCbCr);
|
||||
else
|
||||
return RGB2YCrCb_i<T>(scn, blueIdx, isCbCr); });
|
||||
}
|
||||
|
||||
void cvtYUVtoBGR(const uchar * src_data, size_t src_step,
|
||||
@@ -1997,12 +2036,12 @@ void cvtYUVtoBGR(const uchar * src_data, size_t src_step,
|
||||
CV_INSTRUMENT_REGION();
|
||||
|
||||
int blueIdx = swapBlue ? 2 : 0;
|
||||
if( depth == CV_8U )
|
||||
CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, YCrCb2RGB_i<uchar>(dcn, blueIdx, isCbCr));
|
||||
else if( depth == CV_16U )
|
||||
CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, YCrCb2RGB_i<ushort>(dcn, blueIdx, isCbCr));
|
||||
else
|
||||
CvtColorLoop(src_data, src_step, dst_data, dst_step, width, height, YCrCb2RGB_f<float>(dcn, blueIdx, isCbCr));
|
||||
CvtColorLoopDepth(src_data, src_step, dst_data, dst_step, width, height, depth,
|
||||
[&](auto t){ using T = decltype(t);
|
||||
if constexpr (std::is_same<T, float>::value)
|
||||
return YCrCb2RGB_f<float>(dcn, blueIdx, isCbCr);
|
||||
else
|
||||
return YCrCb2RGB_i<T>(dcn, blueIdx, isCbCr); });
|
||||
}
|
||||
|
||||
// 4:2:0, two planes: Y, UV interleaved
|
||||
|
||||
Reference in New Issue
Block a user