namespace cv
{
-#if defined HAVE_IPP && IPP_VERSION_MAJOR >= 7
+#if defined HAVE_IPP && IPP_VERSION_MAJOR >= 7 && !defined HAVE_IPP_ICV_ONLY
-typedef IppStatus (CV_STDCALL * ippiDCTFwdFunc)(const Ipp32f*, int, Ipp32f*, int, const IppiDCTFwdSpec_32f*, Ipp8u*);
-typedef IppStatus (CV_STDCALL * ippiDCTInvFunc)(const Ipp32f*, int, Ipp32f*, int, const IppiDCTInvSpec_32f*, Ipp8u*);
+typedef IppStatus (CV_STDCALL * ippiDCTFunc)(const Ipp32f*, int, Ipp32f*, int, const void*, Ipp8u*);
+typedef IppStatus (CV_STDCALL * ippiDCTInitAlloc)(void**, IppiSize, IppHintAlgorithm);
+typedef IppStatus (CV_STDCALL * ippiDCTFree)(void* pDCTSpec);
+typedef IppStatus (CV_STDCALL * ippiDCTGetBufSize)(const void*, int*);
-static bool ippi_DCT_Fwd(const Mat& src, Mat& dst, bool row)
+template <typename Dct>
+class DctIPPLoop_Invoker : public ParallelLoopBody
{
- if (src.type() != CV_32F)
- return false;
-
- IppStatus status;
- IppiDCTFwdSpec_32f* pDCTSpec;
- Ipp8u *pBuffer;
- int bufSize=0;
+public:
- ippiDCTFwdFunc ippFunc = (ippiDCTFwdFunc)ippiDCTFwd_32f_C1R;
+ DctIPPLoop_Invoker(const Mat& _src, Mat& _dst, const Dct& _ippidct, bool _inv, bool *_ok) :
+ ParallelLoopBody(), src(_src), dst(_dst), ippidct(_ippidct), inv(_inv), ok(_ok)
+ {
+ *ok = true;
+ }
- if (ippFunc==0)
- return false;
+ virtual void operator()(const Range& range) const
+ {
+ IppStatus status;
+ void* pDCTSpec;
+ AutoBuffer<uchar> buf;
+ uchar* pBuffer = 0;
+ int bufSize=0;
- IppiSize srcRoiSize = {src.cols, row ? 1 : src.rows};
+ IppiSize srcRoiSize = {src.cols, 1};
- CV_SUPPRESS_DEPRECATED_START
- status = ippiDCTFwdInitAlloc_32f (&pDCTSpec, srcRoiSize, ippAlgHintNone);
+ CV_SUPPRESS_DEPRECATED_START
- if ( status < 0 )
- {
- ippiDCTFwdFree_32f(pDCTSpec);
- return false;
- }
+ ippiDCTInitAlloc ippInitAlloc = inv ? (ippiDCTInitAlloc)ippiDCTInvInitAlloc_32f : (ippiDCTInitAlloc)ippiDCTFwdInitAlloc_32f;
+ ippiDCTFree ippFree = inv ? (ippiDCTFree)ippiDCTInvFree_32f : (ippiDCTFree)ippiDCTFwdFree_32f;
+ ippiDCTGetBufSize ippGetBufSize = inv ? (ippiDCTGetBufSize)ippiDCTInvGetBufSize_32f : (ippiDCTGetBufSize)ippiDCTFwdGetBufSize_32f;
- status = ippiDCTFwdGetBufSize_32f (pDCTSpec, &bufSize);
- if ( status < 0 )
- {
- ippiDCTFwdFree_32f(pDCTSpec);
- return false;
- }
+ status = ippInitAlloc(&pDCTSpec, srcRoiSize, ippAlgHintNone);
- pBuffer = ippsMalloc_8u( bufSize );
+ if ( status < 0 )
+ {
+ ippFree(pDCTSpec);
+ *ok = false;
+ return;
+ }
- if (row)
- {
- for (int i=0; i<src.rows; i++)
+ status = ippGetBufSize(pDCTSpec, &bufSize);
+ if ( status < 0 )
{
- status = ippFunc((float*)(src.data+i*src.step), (int)src.step,(float*)(dst.data+i*dst.step), (int)dst.step, pDCTSpec, pBuffer);
- if ( status < 0 )
+ ippFree(pDCTSpec);
+ *ok = false;
+ return;
+ }
+
+ buf.allocate( bufSize );
+ pBuffer = (uchar*)buf;
+
+ for( int i = range.start; i < range.end; ++i)
+ if(!ippidct((float*)(src.data+i*src.step), (int)src.step,(float*)(dst.data+i*dst.step), (int)dst.step, pDCTSpec, (Ipp8u*)pBuffer))
{
- ippsFree( pBuffer );
- ippiDCTFwdFree_32f(pDCTSpec);
- return false;
+ *ok = false;
}
- }
+
+ ippFree( pDCTSpec);
+ CV_SUPPRESS_DEPRECATED_END
}
- else
- status = ippFunc((float*)src.data, (int)src.step, (float*)dst.data, (int)dst.step, pDCTSpec, pBuffer);
- ippsFree( pBuffer );
- ippiDCTFwdFree_32f(pDCTSpec);
- CV_SUPPRESS_DEPRECATED_END
+private:
+ const Mat& src;
+ Mat& dst;
+ const Dct& ippidct;
+ bool inv;
+ bool *ok;
- return status >= 0;
+ const DctIPPLoop_Invoker& operator= (const DctIPPLoop_Invoker&);
+};
+
+template <typename Dct>
+bool DctIPPLoop(const Mat& src, Mat& dst, const Dct& ippidct, bool inv)
+{
+ bool ok;
+ parallel_for_(Range(0, src.rows), DctIPPLoop_Invoker<Dct>(src, dst, ippidct, inv, &ok), src.total()/(double)(1<<16) );
+ return ok;
}
-static bool ippi_DCT_Inv(const Mat& src, Mat& dst, bool row)
+struct IPPDCTFunctor
+{
+ IPPDCTFunctor(ippiDCTFunc _func) : func(_func){}
+
+ bool operator()(const Ipp32f* src, int srcStep, Ipp32f* dst, int dstStep, const void* pDCTSpec, Ipp8u* pBuffer) const
+ {
+ return func ? func(src, srcStep, dst, dstStep, pDCTSpec, pBuffer) >= 0 : false;
+ }
+private:
+ ippiDCTFunc func;
+};
+
+static bool ippi_DCT(const Mat& src, Mat& dst, bool inv, bool row)
{
if (src.type() != CV_32F)
return false;
- IppStatus status;
- IppiDCTInvSpec_32f* pDCTSpec;
- Ipp8u *pBuffer;
- int bufSize=0;
-
- ippiDCTInvFunc ippFunc = (ippiDCTInvFunc)ippiDCTInv_32f_C1R;
+ ippiDCTFunc ippFunc = inv ? (ippiDCTFunc)ippiDCTInv_32f_C1R : (ippiDCTFunc)ippiDCTFwd_32f_C1R ;
- if (ippFunc==0)
- return false;
+ if (row)
+ if(DctIPPLoop(src,dst,IPPDCTFunctor(ippFunc),inv))
+ return true;
+ else
+ return false;
+ else
+ {
+ IppStatus status;
+ void* pDCTSpec;
+ AutoBuffer<uchar> buf;
+ uchar* pBuffer = 0;
+ int bufSize=0;
- IppiSize srcRoiSize = {src.cols, row ? 1 : src.rows};
+ IppiSize srcRoiSize = {src.cols, src.rows};
- CV_SUPPRESS_DEPRECATED_START
- status = ippiDCTInvInitAlloc_32f (&pDCTSpec, srcRoiSize, ippAlgHintNone);
+ CV_SUPPRESS_DEPRECATED_START
- if ( status < 0 )
- {
- ippiDCTInvFree_32f(pDCTSpec);
- return false;
- }
+ ippiDCTInitAlloc ippInitAlloc = inv ? (ippiDCTInitAlloc)ippiDCTInvInitAlloc_32f : (ippiDCTInitAlloc)ippiDCTFwdInitAlloc_32f;
+ ippiDCTFree ippFree = inv ? (ippiDCTFree)ippiDCTInvFree_32f : (ippiDCTFree)ippiDCTFwdFree_32f;
+ ippiDCTGetBufSize ippGetBufSize = inv ? (ippiDCTGetBufSize)ippiDCTInvGetBufSize_32f : (ippiDCTGetBufSize)ippiDCTFwdGetBufSize_32f;
- status = ippiDCTInvGetBufSize_32f (pDCTSpec, &bufSize);
- if ( status < 0 )
- {
- ippiDCTInvFree_32f(pDCTSpec);
- return false;
- }
+ status = ippInitAlloc(&pDCTSpec, srcRoiSize, ippAlgHintNone);
- pBuffer = ippsMalloc_8u( bufSize );
+ if ( status < 0 )
+ {
+ ippFree(pDCTSpec);
+ return false;
+ }
- if (row)
- {
- for (int i=0; i<src.rows; i++)
+ status = ippGetBufSize(pDCTSpec, &bufSize);
+ if ( status < 0 )
{
- status = ippFunc((float*)(src.data+i*src.step), (int)src.step,(float*)(dst.data+i*dst.step), (int)dst.step, pDCTSpec, pBuffer);
- if ( status < 0 )
- {
- ippsFree( pBuffer );
- ippiDCTInvFree_32f(pDCTSpec);
- return false;
- }
+ ippFree(pDCTSpec);
+ return false;
}
- }
- else
- status = ippFunc((float*)src.data, (int)src.step, (float*)dst.data, (int)dst.step, pDCTSpec, pBuffer);
- ippFree( pBuffer );
- ippiDCTInvFree_32f(pDCTSpec);
- CV_SUPPRESS_DEPRECATED_END
+ buf.allocate( bufSize );
+ pBuffer = (uchar*)buf;
- return status >= 0;
+ status = ippFunc((float*)src.data, (int)src.step, (float*)dst.data, (int)dst.step, pDCTSpec, (Ipp8u*)pBuffer);
+
+ ippFree(pDCTSpec);
+ CV_SUPPRESS_DEPRECATED_END
+
+ return status >= 0;
+ }
}
#endif
bool inv = (flags & DCT_INVERSE) != 0;
Mat src0 = _src0.getMat(), src = src0;
int type = src.type(), depth = src.depth();
- void /* *spec_dft = 0, */ *spec = 0;
+ void *spec = 0;
double scale = 1.;
int prev_len = 0, nf = 0, stage, end_stage;
_dst.create( src.rows, src.cols, type );
Mat dst = _dst.getMat();
-#if defined HAVE_IPP && IPP_VERSION_MAJOR >= 7
+#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7) && !defined HAVE_IPP_ICV_ONLY
bool row = (flags & DCT_ROWS) != 0;
- if (inv && ippi_DCT_Inv(src,dst,row))
- return;
- if(ippi_DCT_Fwd(src,dst,row))
- return;
+ if(!row || src.rows>(int)(1<<8))
+ {
+ if(ippi_DCT(src,dst,inv, row))
+ return;
+ setIppErrorStatus();
+ }
#endif
DCTFunc dct_func = dct_tbl[(int)inv + (depth == CV_64F)*2];