1 /*M///////////////////////////////////////////////////////////////////////////////////////
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install,
7 // copy or use the software.
10 // Intel License Agreement
11 // For Open Source Computer Vision Library
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
19 // * Redistribution's of source code must retain the above copyright notice,
20 // this list of conditions and the following disclaimer.
22 // * Redistribution's in binary form must reproduce the above copyright notice,
23 // this list of conditions and the following disclaimer in the documentation
24 // and/or other materials provided with the distribution.
26 // * The name of Intel Corporation may not be used to endorse or promote products
27 // derived from this software without specific prior written permission.
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the Intel Corporation or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
42 #include "precomp.hpp"
43 #include "opencv2/core/opencl/runtime/opencl_clamdfft.hpp"
44 #include "opencv2/core/opencl/runtime/opencl_core.hpp"
45 #include "opencl_kernels_core.hpp"
51 // On Win64 optimized versions of DFT and DCT fail the tests (fixed in VS2010)
52 #if defined _MSC_VER && !defined CV_ICC && defined _M_X64 && _MSC_VER < 1600
53 # pragma optimize("", off)
54 # pragma warning(disable: 4748)
57 #if IPP_VERSION_X100 >= 701
64 /****************************************************************************************\
65 Discrete Fourier Transform
66 \****************************************************************************************/
68 #define CV_MAX_LOCAL_DFT_SIZE (1 << 15)
70 static unsigned char bitrevTab[] =
72 0x00,0x80,0x40,0xc0,0x20,0xa0,0x60,0xe0,0x10,0x90,0x50,0xd0,0x30,0xb0,0x70,0xf0,
73 0x08,0x88,0x48,0xc8,0x28,0xa8,0x68,0xe8,0x18,0x98,0x58,0xd8,0x38,0xb8,0x78,0xf8,
74 0x04,0x84,0x44,0xc4,0x24,0xa4,0x64,0xe4,0x14,0x94,0x54,0xd4,0x34,0xb4,0x74,0xf4,
75 0x0c,0x8c,0x4c,0xcc,0x2c,0xac,0x6c,0xec,0x1c,0x9c,0x5c,0xdc,0x3c,0xbc,0x7c,0xfc,
76 0x02,0x82,0x42,0xc2,0x22,0xa2,0x62,0xe2,0x12,0x92,0x52,0xd2,0x32,0xb2,0x72,0xf2,
77 0x0a,0x8a,0x4a,0xca,0x2a,0xaa,0x6a,0xea,0x1a,0x9a,0x5a,0xda,0x3a,0xba,0x7a,0xfa,
78 0x06,0x86,0x46,0xc6,0x26,0xa6,0x66,0xe6,0x16,0x96,0x56,0xd6,0x36,0xb6,0x76,0xf6,
79 0x0e,0x8e,0x4e,0xce,0x2e,0xae,0x6e,0xee,0x1e,0x9e,0x5e,0xde,0x3e,0xbe,0x7e,0xfe,
80 0x01,0x81,0x41,0xc1,0x21,0xa1,0x61,0xe1,0x11,0x91,0x51,0xd1,0x31,0xb1,0x71,0xf1,
81 0x09,0x89,0x49,0xc9,0x29,0xa9,0x69,0xe9,0x19,0x99,0x59,0xd9,0x39,0xb9,0x79,0xf9,
82 0x05,0x85,0x45,0xc5,0x25,0xa5,0x65,0xe5,0x15,0x95,0x55,0xd5,0x35,0xb5,0x75,0xf5,
83 0x0d,0x8d,0x4d,0xcd,0x2d,0xad,0x6d,0xed,0x1d,0x9d,0x5d,0xdd,0x3d,0xbd,0x7d,0xfd,
84 0x03,0x83,0x43,0xc3,0x23,0xa3,0x63,0xe3,0x13,0x93,0x53,0xd3,0x33,0xb3,0x73,0xf3,
85 0x0b,0x8b,0x4b,0xcb,0x2b,0xab,0x6b,0xeb,0x1b,0x9b,0x5b,0xdb,0x3b,0xbb,0x7b,0xfb,
86 0x07,0x87,0x47,0xc7,0x27,0xa7,0x67,0xe7,0x17,0x97,0x57,0xd7,0x37,0xb7,0x77,0xf7,
87 0x0f,0x8f,0x4f,0xcf,0x2f,0xaf,0x6f,0xef,0x1f,0x9f,0x5f,0xdf,0x3f,0xbf,0x7f,0xff
90 static const double DFTTab[][2] =
92 { 1.00000000000000000, 0.00000000000000000 },
93 {-1.00000000000000000, 0.00000000000000000 },
94 { 0.00000000000000000, 1.00000000000000000 },
95 { 0.70710678118654757, 0.70710678118654746 },
96 { 0.92387953251128674, 0.38268343236508978 },
97 { 0.98078528040323043, 0.19509032201612825 },
98 { 0.99518472667219693, 0.09801714032956060 },
99 { 0.99879545620517241, 0.04906767432741802 },
100 { 0.99969881869620425, 0.02454122852291229 },
101 { 0.99992470183914450, 0.01227153828571993 },
102 { 0.99998117528260111, 0.00613588464915448 },
103 { 0.99999529380957619, 0.00306795676296598 },
104 { 0.99999882345170188, 0.00153398018628477 },
105 { 0.99999970586288223, 0.00076699031874270 },
106 { 0.99999992646571789, 0.00038349518757140 },
107 { 0.99999998161642933, 0.00019174759731070 },
108 { 0.99999999540410733, 0.00009587379909598 },
109 { 0.99999999885102686, 0.00004793689960307 },
110 { 0.99999999971275666, 0.00002396844980842 },
111 { 0.99999999992818922, 0.00001198422490507 },
112 { 0.99999999998204725, 0.00000599211245264 },
113 { 0.99999999999551181, 0.00000299605622633 },
114 { 0.99999999999887801, 0.00000149802811317 },
115 { 0.99999999999971945, 0.00000074901405658 },
116 { 0.99999999999992983, 0.00000037450702829 },
117 { 0.99999999999998246, 0.00000018725351415 },
118 { 0.99999999999999567, 0.00000009362675707 },
119 { 0.99999999999999889, 0.00000004681337854 },
120 { 0.99999999999999978, 0.00000002340668927 },
121 { 0.99999999999999989, 0.00000001170334463 },
122 { 1.00000000000000000, 0.00000000585167232 },
123 { 1.00000000000000000, 0.00000000292583616 }
126 #define BitRev(i,shift) \
127 ((int)((((unsigned)bitrevTab[(i)&255] << 24)+ \
128 ((unsigned)bitrevTab[((i)>> 8)&255] << 16)+ \
129 ((unsigned)bitrevTab[((i)>>16)&255] << 8)+ \
130 ((unsigned)bitrevTab[((i)>>24)])) >> (shift)))
133 DFTFactorize( int n, int* factors )
143 f = (((n - 1)^n)+1) >> 1;
147 n = f == n ? 1 : n/f;
169 f = (factors[0] & 1) == 0;
170 for( i = f; i < (nf+f)/2; i++ )
171 CV_SWAP( factors[i], factors[nf-i-1+f], j );
177 DFTInit( int n0, int nf, int* factors, int* itab, int elem_size, void* _wave, int inv_itab )
179 int digits[34], radix[34];
180 int n = factors[0], m = 0;
183 Complex<double> w, w1;
193 for( i = 1; i < n0-1; i++ )
203 if( elem_size == sizeof(Complex<double>) )
204 ((Complex<double>*)_wave)[0] = Complex<double>(1.,0.);
206 ((Complex<float>*)_wave)[0] = Complex<float>(1.f,0.f);
214 // radix[] is initialized from index 'nf' down to zero
218 for( i = 0; i < nf; i++ )
221 radix[nf-i-1] = radix[nf-i]*factors[nf-i-1];
224 if( inv_itab && factors[0] != factors[nf-1] )
229 int a = radix[1], na2 = n*a>>1, na4 = na2 >> 1;
230 for( m = 0; (unsigned)(1 << m) < (unsigned)n; m++ )
240 for( i = 0; i <= n - 4; i += 4 )
242 j = (bitrevTab[i>>2]>>shift)*a;
246 itab[i+3] = j + na2 + na4;
252 for( i = 0; i < n; i += 4 )
255 j = BitRev(i4,shift)*a;
259 itab[i+3] = j + na2 + na4;
267 for( i = n, j = radix[2]; i < n0; )
269 for( k = 0; k < n; k++ )
270 itab[i+k] = itab[k] + j;
274 for( k = 1; ++digits[k] >= factors[k]; k++ )
277 j += radix[k+2] - radix[k];
284 for( i = 0, j = 0;; )
290 for( k = 0; ++digits[k] >= factors[k]; k++ )
293 j += radix[k+2] - radix[k];
301 for( i = n0 & 1; i < n0; i += 2 )
311 if( (n0 & (n0-1)) == 0 )
313 w.re = w1.re = DFTTab[m][0];
314 w.im = w1.im = -DFTTab[m][1];
319 w.im = w1.im = sin(t);
320 w.re = w1.re = std::sqrt(1. - w1.im*w1.im);
324 if( elem_size == sizeof(Complex<double>) )
326 Complex<double>* wave = (Complex<double>*)_wave;
337 for( i = 1; i < n; i++ )
340 wave[n0-i].re = w.re;
341 wave[n0-i].im = -w.im;
343 t = w.re*w1.re - w.im*w1.im;
344 w.im = w.re*w1.im + w.im*w1.re;
350 Complex<float>* wave = (Complex<float>*)_wave;
351 assert( elem_size == sizeof(Complex<float>) );
362 for( i = 1; i < n; i++ )
364 wave[i].re = (float)w.re;
365 wave[i].im = (float)w.im;
366 wave[n0-i].re = (float)w.re;
367 wave[n0-i].im = (float)-w.im;
369 t = w.re*w1.re - w.im*w1.im;
370 w.im = w.re*w1.im + w.im*w1.re;
376 template<typename T> struct DFT_VecR4
378 int operator()(Complex<T>*, int, int, int&, const Complex<T>*) const { return 1; }
383 // optimized radix-4 transform
384 template<> struct DFT_VecR4<float>
386 int operator()(Complex<float>* dst, int N, int n0, int& _dw0, const Complex<float>* wave) const
388 int n = 1, i, j, nx, dw, dw0 = _dw0;
389 __m128 z = _mm_setzero_ps(), x02=z, x13=z, w01=z, w23=z, y01, y23, t0, t1;
390 Cv32suf t; t.i = 0x80000000;
391 __m128 neg0_mask = _mm_load_ss(&t.f);
392 __m128 neg3_mask = _mm_shuffle_ps(neg0_mask, neg0_mask, _MM_SHUFFLE(0,1,2,3));
400 for( i = 0; i < n0; i += n )
407 x02 = _mm_loadl_pi(x02, (const __m64*)&v0[0]);
408 x13 = _mm_loadl_pi(x13, (const __m64*)&v0[nx]);
409 x02 = _mm_loadh_pi(x02, (const __m64*)&v1[0]);
410 x13 = _mm_loadh_pi(x13, (const __m64*)&v1[nx]);
412 y01 = _mm_add_ps(x02, x13);
413 y23 = _mm_sub_ps(x02, x13);
414 t1 = _mm_xor_ps(_mm_shuffle_ps(y01, y23, _MM_SHUFFLE(2,3,3,2)), neg3_mask);
415 t0 = _mm_movelh_ps(y01, y23);
416 y01 = _mm_add_ps(t0, t1);
417 y23 = _mm_sub_ps(t0, t1);
419 _mm_storel_pi((__m64*)&v0[0], y01);
420 _mm_storeh_pi((__m64*)&v0[nx], y01);
421 _mm_storel_pi((__m64*)&v1[0], y23);
422 _mm_storeh_pi((__m64*)&v1[nx], y23);
424 for( j = 1, dw = dw0; j < nx; j++, dw += dw0 )
429 x13 = _mm_loadl_pi(x13, (const __m64*)&v0[nx]);
430 w23 = _mm_loadl_pi(w23, (const __m64*)&wave[dw*2]);
431 x13 = _mm_loadh_pi(x13, (const __m64*)&v1[nx]); // x1, x3 = r1 i1 r3 i3
432 w23 = _mm_loadh_pi(w23, (const __m64*)&wave[dw*3]); // w2, w3 = wr2 wi2 wr3 wi3
434 t0 = _mm_mul_ps(_mm_moveldup_ps(x13), w23);
435 t1 = _mm_mul_ps(_mm_movehdup_ps(x13), _mm_shuffle_ps(w23, w23, _MM_SHUFFLE(2,3,0,1)));
436 x13 = _mm_addsub_ps(t0, t1);
437 // re(x1*w2), im(x1*w2), re(x3*w3), im(x3*w3)
438 x02 = _mm_loadl_pi(x02, (const __m64*)&v1[0]); // x2 = r2 i2
439 w01 = _mm_loadl_pi(w01, (const __m64*)&wave[dw]); // w1 = wr1 wi1
440 x02 = _mm_shuffle_ps(x02, x02, _MM_SHUFFLE(0,0,1,1));
441 w01 = _mm_shuffle_ps(w01, w01, _MM_SHUFFLE(1,0,0,1));
442 x02 = _mm_mul_ps(x02, w01);
443 x02 = _mm_addsub_ps(x02, _mm_movelh_ps(x02, x02));
444 // re(x0) im(x0) re(x2*w1), im(x2*w1)
445 x02 = _mm_loadl_pi(x02, (const __m64*)&v0[0]);
447 y01 = _mm_add_ps(x02, x13);
448 y23 = _mm_sub_ps(x02, x13);
449 t1 = _mm_xor_ps(_mm_shuffle_ps(y01, y23, _MM_SHUFFLE(2,3,3,2)), neg3_mask);
450 t0 = _mm_movelh_ps(y01, y23);
451 y01 = _mm_add_ps(t0, t1);
452 y23 = _mm_sub_ps(t0, t1);
454 _mm_storel_pi((__m64*)&v0[0], y01);
455 _mm_storeh_pi((__m64*)&v0[nx], y01);
456 _mm_storel_pi((__m64*)&v1[0], y23);
457 _mm_storeh_pi((__m64*)&v1[nx], y23);
470 static IppStatus ippsDFTFwd_CToC( const Complex<float>* src, Complex<float>* dst,
471 const void* spec, uchar* buf)
473 return ippsDFTFwd_CToC_32fc( (const Ipp32fc*)src, (Ipp32fc*)dst,
474 (const IppsDFTSpec_C_32fc*)spec, buf);
477 static IppStatus ippsDFTFwd_CToC( const Complex<double>* src, Complex<double>* dst,
478 const void* spec, uchar* buf)
480 return ippsDFTFwd_CToC_64fc( (const Ipp64fc*)src, (Ipp64fc*)dst,
481 (const IppsDFTSpec_C_64fc*)spec, buf);
484 static IppStatus ippsDFTInv_CToC( const Complex<float>* src, Complex<float>* dst,
485 const void* spec, uchar* buf)
487 return ippsDFTInv_CToC_32fc( (const Ipp32fc*)src, (Ipp32fc*)dst,
488 (const IppsDFTSpec_C_32fc*)spec, buf);
491 static IppStatus ippsDFTInv_CToC( const Complex<double>* src, Complex<double>* dst,
492 const void* spec, uchar* buf)
494 return ippsDFTInv_CToC_64fc( (const Ipp64fc*)src, (Ipp64fc*)dst,
495 (const IppsDFTSpec_C_64fc*)spec, buf);
498 static IppStatus ippsDFTFwd_RToPack( const float* src, float* dst,
499 const void* spec, uchar* buf)
501 return ippsDFTFwd_RToPack_32f( src, dst, (const IppsDFTSpec_R_32f*)spec, buf);
504 static IppStatus ippsDFTFwd_RToPack( const double* src, double* dst,
505 const void* spec, uchar* buf)
507 return ippsDFTFwd_RToPack_64f( src, dst, (const IppsDFTSpec_R_64f*)spec, buf);
510 static IppStatus ippsDFTInv_PackToR( const float* src, float* dst,
511 const void* spec, uchar* buf)
513 return ippsDFTInv_PackToR_32f( src, dst, (const IppsDFTSpec_R_32f*)spec, buf);
516 static IppStatus ippsDFTInv_PackToR( const double* src, double* dst,
517 const void* spec, uchar* buf)
519 return ippsDFTInv_PackToR_64f( src, dst, (const IppsDFTSpec_R_64f*)spec, buf);
523 enum { DFT_NO_PERMUTE=256, DFT_COMPLEX_INPUT_OR_OUTPUT=512 };
525 // mixed-radix complex discrete Fourier transform: double-precision version
526 template<typename T> static void
527 DFT( const Complex<T>* src, Complex<T>* dst, int n,
528 int nf, const int* factors, const int* itab,
529 const Complex<T>* wave, int tab_size,
535 int flags, double _scale )
537 static const T sin_120 = (T)0.86602540378443864676372317075294;
538 static const T fft5_2 = (T)0.559016994374947424102293417182819;
539 static const T fft5_3 = (T)-0.951056516295153572116439333379382;
540 static const T fft5_4 = (T)-1.538841768587626701285145288018455;
541 static const T fft5_5 = (T)0.363271264002680442947733378740309;
543 int n0 = n, f_idx, nx;
544 int inv = flags & DFT_INVERSE;
545 int dw0 = tab_size, dw;
556 if (ippsDFTFwd_CToC( src, dst, spec, (uchar*)buf ) >= 0)
558 CV_IMPL_ADD(CV_IMPL_IPP);
564 if (ippsDFTInv_CToC( src, dst, spec, (uchar*)buf ) >= 0)
566 CV_IMPL_ADD(CV_IMPL_IPP);
574 tab_step = tab_size == n ? 1 : tab_size == n*2 ? 2 : tab_size/n;
579 assert( (flags & DFT_NO_PERMUTE) == 0 );
582 for( i = 0; i <= n - 2; i += 2, itab += 2*tab_step )
584 int k0 = itab[0], k1 = itab[tab_step];
585 assert( (unsigned)k0 < (unsigned)n && (unsigned)k1 < (unsigned)n );
586 dst[i] = src[k0]; dst[i+1] = src[k1];
594 for( i = 0; i <= n - 2; i += 2, itab += 2*tab_step )
596 int k0 = itab[0], k1 = itab[tab_step];
597 assert( (unsigned)k0 < (unsigned)n && (unsigned)k1 < (unsigned)n );
598 t.re = src[k0].re; t.im = -src[k0].im;
600 t.re = src[k1].re; t.im = -src[k1].im;
606 t.re = src[n-1].re; t.im = -src[n-1].im;
613 if( (flags & DFT_NO_PERMUTE) == 0 )
615 CV_Assert( factors[0] == factors[nf-1] );
621 Complex<T>* dsth = dst + n2;
623 for( i = 0; i < n2; i += 2, itab += tab_step*2 )
626 assert( (unsigned)j < (unsigned)n2 );
628 CV_SWAP(dst[i+1], dsth[j], t);
631 CV_SWAP(dst[i], dst[j], t);
632 CV_SWAP(dsth[i+1], dsth[j+1], t);
640 for( i = 0; i < n; i++, itab += tab_step )
643 assert( (unsigned)j < (unsigned)n );
645 CV_SWAP(dst[i], dst[j], t);
652 for( i = 0; i <= n - 2; i += 2 )
656 dst[i].im = t0; dst[i+1].im = t1;
660 dst[n-1].im = -dst[n-1].im;
665 // 1. power-2 transforms
666 if( (factors[0] & 1) == 0 )
668 if( factors[0] >= 4 && checkHardwareSupport(CV_CPU_SSE3))
671 n = vr4(dst, factors[0], n0, dw0, wave);
675 for( ; n*4 <= factors[0]; )
681 for( i = 0; i < n0; i += n )
684 T r0, i0, r1, i1, r2, i2, r3, i3, r4, i4;
689 r0 = v1[0].re; i0 = v1[0].im;
690 r4 = v1[nx].re; i4 = v1[nx].im;
692 r1 = r0 + r4; i1 = i0 + i4;
693 r3 = i0 - i4; i3 = r4 - r0;
695 r2 = v0[0].re; i2 = v0[0].im;
696 r4 = v0[nx].re; i4 = v0[nx].im;
698 r0 = r2 + r4; i0 = i2 + i4;
701 v0[0].re = r0 + r1; v0[0].im = i0 + i1;
702 v1[0].re = r0 - r1; v1[0].im = i0 - i1;
703 v0[nx].re = r2 + r3; v0[nx].im = i2 + i3;
704 v1[nx].re = r2 - r3; v1[nx].im = i2 - i3;
706 for( j = 1, dw = dw0; j < nx; j++, dw += dw0 )
711 r2 = v0[nx].re*wave[dw*2].re - v0[nx].im*wave[dw*2].im;
712 i2 = v0[nx].re*wave[dw*2].im + v0[nx].im*wave[dw*2].re;
713 r0 = v1[0].re*wave[dw].im + v1[0].im*wave[dw].re;
714 i0 = v1[0].re*wave[dw].re - v1[0].im*wave[dw].im;
715 r3 = v1[nx].re*wave[dw*3].im + v1[nx].im*wave[dw*3].re;
716 i3 = v1[nx].re*wave[dw*3].re - v1[nx].im*wave[dw*3].im;
718 r1 = i0 + i3; i1 = r0 + r3;
719 r3 = r0 - r3; i3 = i3 - i0;
720 r4 = v0[0].re; i4 = v0[0].im;
722 r0 = r4 + r2; i0 = i4 + i2;
723 r2 = r4 - r2; i2 = i4 - i2;
725 v0[0].re = r0 + r1; v0[0].im = i0 + i1;
726 v1[0].re = r0 - r1; v1[0].im = i0 - i1;
727 v0[nx].re = r2 + r3; v0[nx].im = i2 + i3;
728 v1[nx].re = r2 - r3; v1[nx].im = i2 - i3;
733 for( ; n < factors[0]; )
735 // do the remaining radix-2 transform
740 for( i = 0; i < n0; i += n )
742 Complex<T>* v = dst + i;
743 T r0 = v[0].re + v[nx].re;
744 T i0 = v[0].im + v[nx].im;
745 T r1 = v[0].re - v[nx].re;
746 T i1 = v[0].im - v[nx].im;
747 v[0].re = r0; v[0].im = i0;
748 v[nx].re = r1; v[nx].im = i1;
750 for( j = 1, dw = dw0; j < nx; j++, dw += dw0 )
753 r1 = v[nx].re*wave[dw].re - v[nx].im*wave[dw].im;
754 i1 = v[nx].im*wave[dw].re + v[nx].re*wave[dw].im;
755 r0 = v[0].re; i0 = v[0].im;
757 v[0].re = r0 + r1; v[0].im = i0 + i1;
758 v[nx].re = r0 - r1; v[nx].im = i0 - i1;
764 // 2. all the other transforms
765 for( f_idx = (factors[0]&1) ? 0 : 1; f_idx < nf; f_idx++ )
767 int factor = factors[f_idx];
775 for( i = 0; i < n0; i += n )
777 Complex<T>* v = dst + i;
779 T r1 = v[nx].re + v[nx*2].re;
780 T i1 = v[nx].im + v[nx*2].im;
783 T r2 = sin_120*(v[nx].im - v[nx*2].im);
784 T i2 = sin_120*(v[nx*2].re - v[nx].re);
785 v[0].re = r0 + r1; v[0].im = i0 + i1;
786 r0 -= (T)0.5*r1; i0 -= (T)0.5*i1;
787 v[nx].re = r0 + r2; v[nx].im = i0 + i2;
788 v[nx*2].re = r0 - r2; v[nx*2].im = i0 - i2;
790 for( j = 1, dw = dw0; j < nx; j++, dw += dw0 )
793 r0 = v[nx].re*wave[dw].re - v[nx].im*wave[dw].im;
794 i0 = v[nx].re*wave[dw].im + v[nx].im*wave[dw].re;
795 i2 = v[nx*2].re*wave[dw*2].re - v[nx*2].im*wave[dw*2].im;
796 r2 = v[nx*2].re*wave[dw*2].im + v[nx*2].im*wave[dw*2].re;
797 r1 = r0 + i2; i1 = i0 + r2;
799 r2 = sin_120*(i0 - r2); i2 = sin_120*(i2 - r0);
800 r0 = v[0].re; i0 = v[0].im;
801 v[0].re = r0 + r1; v[0].im = i0 + i1;
802 r0 -= (T)0.5*r1; i0 -= (T)0.5*i1;
803 v[nx].re = r0 + r2; v[nx].im = i0 + i2;
804 v[nx*2].re = r0 - r2; v[nx*2].im = i0 - i2;
808 else if( factor == 5 )
811 for( i = 0; i < n0; i += n )
813 for( j = 0, dw = 0; j < nx; j++, dw += dw0 )
815 Complex<T>* v0 = dst + i + j;
816 Complex<T>* v1 = v0 + nx*2;
817 Complex<T>* v2 = v1 + nx*2;
819 T r0, i0, r1, i1, r2, i2, r3, i3, r4, i4, r5, i5;
821 r3 = v0[nx].re*wave[dw].re - v0[nx].im*wave[dw].im;
822 i3 = v0[nx].re*wave[dw].im + v0[nx].im*wave[dw].re;
823 r2 = v2[0].re*wave[dw*4].re - v2[0].im*wave[dw*4].im;
824 i2 = v2[0].re*wave[dw*4].im + v2[0].im*wave[dw*4].re;
826 r1 = r3 + r2; i1 = i3 + i2;
829 r4 = v1[nx].re*wave[dw*3].re - v1[nx].im*wave[dw*3].im;
830 i4 = v1[nx].re*wave[dw*3].im + v1[nx].im*wave[dw*3].re;
831 r0 = v1[0].re*wave[dw*2].re - v1[0].im*wave[dw*2].im;
832 i0 = v1[0].re*wave[dw*2].im + v1[0].im*wave[dw*2].re;
834 r2 = r4 + r0; i2 = i4 + i0;
837 r0 = v0[0].re; i0 = v0[0].im;
838 r5 = r1 + r2; i5 = i1 + i2;
840 v0[0].re = r0 + r5; v0[0].im = i0 + i5;
842 r0 -= (T)0.25*r5; i0 -= (T)0.25*i5;
843 r1 = fft5_2*(r1 - r2); i1 = fft5_2*(i1 - i2);
844 r2 = -fft5_3*(i3 + i4); i2 = fft5_3*(r3 + r4);
846 i3 *= -fft5_5; r3 *= fft5_5;
847 i4 *= -fft5_4; r4 *= fft5_4;
849 r5 = r2 + i3; i5 = i2 + r3;
852 r3 = r0 + r1; i3 = i0 + i1;
855 v0[nx].re = r3 + r2; v0[nx].im = i3 + i2;
856 v2[0].re = r3 - r2; v2[0].im = i3 - i2;
858 v1[0].re = r0 + r5; v1[0].im = i0 + i5;
859 v1[nx].re = r0 - r5; v1[nx].im = i0 - i5;
865 // radix-"factor" - an odd number
866 int p, q, factor2 = (factor - 1)/2;
867 int d, dd, dw_f = tab_size/factor;
869 Complex<T>* b = buf + factor2;
871 for( i = 0; i < n0; i += n )
873 for( j = 0, dw = 0; j < nx; j++, dw += dw0 )
875 Complex<T>* v = dst + i + j;
876 Complex<T> v_0 = v[0];
877 Complex<T> vn_0 = v_0;
881 for( p = 1, k = nx; p <= factor2; p++, k += nx )
883 T r0 = v[k].re + v[n-k].re;
884 T i0 = v[k].im - v[n-k].im;
885 T r1 = v[k].re - v[n-k].re;
886 T i1 = v[k].im + v[n-k].im;
888 vn_0.re += r0; vn_0.im += i1;
889 a[p-1].re = r0; a[p-1].im = i0;
890 b[p-1].re = r1; b[p-1].im = i1;
895 const Complex<T>* wave_ = wave + dw*factor;
898 for( p = 1, k = nx; p <= factor2; p++, k += nx, d += dw )
900 T r2 = v[k].re*wave[d].re - v[k].im*wave[d].im;
901 T i2 = v[k].re*wave[d].im + v[k].im*wave[d].re;
903 T r1 = v[n-k].re*wave_[-d].re - v[n-k].im*wave_[-d].im;
904 T i1 = v[n-k].re*wave_[-d].im + v[n-k].im*wave_[-d].re;
911 vn_0.re += r0; vn_0.im += i1;
912 a[p-1].re = r0; a[p-1].im = i0;
913 b[p-1].re = r1; b[p-1].im = i1;
919 for( p = 1, k = nx; p <= factor2; p++, k += nx )
921 Complex<T> s0 = v_0, s1 = v_0;
924 for( q = 0; q < factor2; q++ )
926 T r0 = wave[d].re * a[q].re;
927 T i0 = wave[d].im * a[q].im;
928 T r1 = wave[d].re * b[q].im;
929 T i1 = wave[d].im * b[q].re;
931 s1.re += r0 + i0; s0.re += r0 - i0;
932 s1.im += r1 - i1; s0.im += r1 + i1;
935 d -= -(d >= tab_size) & tab_size;
948 T re_scale = scale, im_scale = scale;
950 im_scale = -im_scale;
952 for( i = 0; i < n0; i++ )
954 T t0 = dst[i].re*re_scale;
955 T t1 = dst[i].im*im_scale;
962 for( i = 0; i <= n0 - 2; i += 2 )
971 dst[n0-1].im = -dst[n0-1].im;
976 /* FFT of real vector
977 output vector format:
978 re(0), re(1), im(1), ... , re(n/2-1), im((n+1)/2-1) [, re((n+1)/2)] OR ...
979 re(0), 0, re(1), im(1), ..., re(n/2-1), im((n+1)/2-1) [, re((n+1)/2), 0] */
980 template<typename T> static void
981 RealDFT( const T* src, T* dst, int n, int nf, int* factors, const int* itab,
982 const Complex<T>* wave, int tab_size, const void*
987 Complex<T>* buf, int flags, double _scale )
989 int complex_output = (flags & DFT_COMPLEX_INPUT_OR_OUTPUT) != 0;
992 dst += complex_output;
997 if (ippsDFTFwd_RToPack( src, dst, spec, (uchar*)buf ) >=0)
1006 CV_IMPL_ADD(CV_IMPL_IPP);
1009 setIppErrorStatus();
1012 assert( tab_size == n );
1016 dst[0] = src[0]*scale;
1020 T t = (src[0] + src[1])*scale;
1021 dst[1] = (src[0] - src[1])*scale;
1026 dst -= complex_output;
1027 Complex<T>* _dst = (Complex<T>*)dst;
1028 _dst[0].re = src[0]*scale;
1030 for( j = 1; j < n; j += 2 )
1032 T t0 = src[itab[j]]*scale;
1033 T t1 = src[itab[j+1]]*scale;
1039 DFT( _dst, _dst, n, nf, factors, itab, wave,
1040 tab_size, 0, buf, DFT_NO_PERMUTE, 1 );
1041 if( !complex_output )
1047 T h1_re, h1_im, h2_re, h2_im;
1048 T scale2 = scale*(T)0.5;
1051 DFT( (Complex<T>*)src, (Complex<T>*)dst, n2, nf - (factors[0] == 1),
1052 factors + (factors[0] == 1),
1053 itab, wave, tab_size, 0, buf, 0, 1 );
1056 t = dst[0] - dst[1];
1057 dst[0] = (dst[0] + dst[1])*scale;
1064 for( j = 2, wave++; j < n2; j += 2, wave++ )
1067 h2_re = scale2*(dst[j+1] + t);
1068 h2_im = scale2*(dst[n-j] - dst[j]);
1071 h1_re = scale2*(dst[j] + dst[n-j]);
1072 h1_im = scale2*(dst[j+1] - t);
1075 t = h2_re*wave->re - h2_im*wave->im;
1076 h2_im = h2_re*wave->im + h2_im*wave->re;
1080 dst[j-1] = h1_re + h2_re;
1081 dst[n-j-1] = h1_re - h2_re;
1082 dst[j] = h1_im + h2_im;
1083 dst[n-j] = h2_im - h1_im;
1088 dst[n2-1] = t0*scale;
1093 if( complex_output && (n & 1) == 0 )
1101 /* Inverse FFT of complex conjugate-symmetric vector
1102 input vector format:
1103 re[0], re[1], im[1], ... , re[n/2-1], im[n/2-1], re[n/2] OR
1104 re(0), 0, re(1), im(1), ..., re(n/2-1), im((n+1)/2-1) [, re((n+1)/2), 0] */
1105 template<typename T> static void
1106 CCSIDFT( const T* src, T* dst, int n, int nf, int* factors, const int* itab,
1107 const Complex<T>* wave, int tab_size,
1113 int flags, double _scale )
1115 int complex_input = (flags & DFT_COMPLEX_INPUT_OR_OUTPUT) != 0;
1116 int j, k, n2 = (n+1) >> 1;
1117 T scale = (T)_scale;
1119 T t0, t1, t2, t3, t;
1121 assert( tab_size == n );
1125 assert( src != dst );
1127 ((T*)src)[1] = src[0];
1133 if (ippsDFTInv_PackToR( src, dst, spec, (uchar*)buf ) >=0)
1136 ((T*)src)[0] = (T)save_s1;
1137 CV_IMPL_ADD(CV_IMPL_IPP);
1141 setIppErrorStatus();
1146 dst[0] = (T)(src[0]*scale);
1150 t = (src[0] + src[1])*scale;
1151 dst[1] = (src[0] - src[1])*scale;
1156 Complex<T>* _src = (Complex<T>*)(src-1);
1157 Complex<T>* _dst = (Complex<T>*)dst;
1159 _dst[0].re = src[0];
1161 for( j = 1; j < n2; j++ )
1163 int k0 = itab[j], k1 = itab[n-j];
1164 t0 = _src[j].re; t1 = _src[j].im;
1165 _dst[k0].re = t0; _dst[k0].im = -t1;
1166 _dst[k1].re = t0; _dst[k1].im = t1;
1169 DFT( _dst, _dst, n, nf, factors, itab, wave,
1170 tab_size, 0, buf, DFT_NO_PERMUTE, 1. );
1172 for( j = 1; j < n; j += 2 )
1174 t0 = dst[j*2]*scale;
1175 t1 = dst[j*2+2]*scale;
1182 int inplace = src == dst;
1183 const Complex<T>* w = wave;
1186 t0 = (src[0] + src[n-1]);
1187 t1 = (src[n-1] - src[0]);
1191 for( j = 2, w++; j < n2; j += 2, w++ )
1193 T h1_re, h1_im, h2_re, h2_im;
1195 h1_re = (t + src[n-j-1]);
1196 h1_im = (src[j] - src[n-j]);
1198 h2_re = (t - src[n-j-1]);
1199 h2_im = (src[j] + src[n-j]);
1201 t = h2_re*w->re + h2_im*w->im;
1202 h2_im = h2_im*w->re - h2_re*w->im;
1207 t1 = -h1_im - h2_re;
1249 DFT( (Complex<T>*)dst, (Complex<T>*)dst, n2,
1250 nf - (factors[0] == 1),
1251 factors + (factors[0] == 1), itab,
1252 wave, tab_size, 0, buf,
1253 inplace ? 0 : DFT_NO_PERMUTE, 1. );
1256 for( j = 0; j < n; j += 2 )
1259 t1 = dst[j+1]*(-scale);
1265 ((T*)src)[0] = (T)save_s1;
1269 CopyColumn( const uchar* _src, size_t src_step,
1270 uchar* _dst, size_t dst_step,
1271 int len, size_t elem_size )
1274 const int* src = (const int*)_src;
1275 int* dst = (int*)_dst;
1276 src_step /= sizeof(src[0]);
1277 dst_step /= sizeof(dst[0]);
1279 if( elem_size == sizeof(int) )
1281 for( i = 0; i < len; i++, src += src_step, dst += dst_step )
1284 else if( elem_size == sizeof(int)*2 )
1286 for( i = 0; i < len; i++, src += src_step, dst += dst_step )
1288 t0 = src[0]; t1 = src[1];
1289 dst[0] = t0; dst[1] = t1;
1292 else if( elem_size == sizeof(int)*4 )
1294 for( i = 0; i < len; i++, src += src_step, dst += dst_step )
1296 t0 = src[0]; t1 = src[1];
1297 dst[0] = t0; dst[1] = t1;
1298 t0 = src[2]; t1 = src[3];
1299 dst[2] = t0; dst[3] = t1;
1306 CopyFrom2Columns( const uchar* _src, size_t src_step,
1307 uchar* _dst0, uchar* _dst1,
1308 int len, size_t elem_size )
1311 const int* src = (const int*)_src;
1312 int* dst0 = (int*)_dst0;
1313 int* dst1 = (int*)_dst1;
1314 src_step /= sizeof(src[0]);
1316 if( elem_size == sizeof(int) )
1318 for( i = 0; i < len; i++, src += src_step )
1320 t0 = src[0]; t1 = src[1];
1321 dst0[i] = t0; dst1[i] = t1;
1324 else if( elem_size == sizeof(int)*2 )
1326 for( i = 0; i < len*2; i += 2, src += src_step )
1328 t0 = src[0]; t1 = src[1];
1329 dst0[i] = t0; dst0[i+1] = t1;
1330 t0 = src[2]; t1 = src[3];
1331 dst1[i] = t0; dst1[i+1] = t1;
1334 else if( elem_size == sizeof(int)*4 )
1336 for( i = 0; i < len*4; i += 4, src += src_step )
1338 t0 = src[0]; t1 = src[1];
1339 dst0[i] = t0; dst0[i+1] = t1;
1340 t0 = src[2]; t1 = src[3];
1341 dst0[i+2] = t0; dst0[i+3] = t1;
1342 t0 = src[4]; t1 = src[5];
1343 dst1[i] = t0; dst1[i+1] = t1;
1344 t0 = src[6]; t1 = src[7];
1345 dst1[i+2] = t0; dst1[i+3] = t1;
1352 CopyTo2Columns( const uchar* _src0, const uchar* _src1,
1353 uchar* _dst, size_t dst_step,
1354 int len, size_t elem_size )
1357 const int* src0 = (const int*)_src0;
1358 const int* src1 = (const int*)_src1;
1359 int* dst = (int*)_dst;
1360 dst_step /= sizeof(dst[0]);
1362 if( elem_size == sizeof(int) )
1364 for( i = 0; i < len; i++, dst += dst_step )
1366 t0 = src0[i]; t1 = src1[i];
1367 dst[0] = t0; dst[1] = t1;
1370 else if( elem_size == sizeof(int)*2 )
1372 for( i = 0; i < len*2; i += 2, dst += dst_step )
1374 t0 = src0[i]; t1 = src0[i+1];
1375 dst[0] = t0; dst[1] = t1;
1376 t0 = src1[i]; t1 = src1[i+1];
1377 dst[2] = t0; dst[3] = t1;
1380 else if( elem_size == sizeof(int)*4 )
1382 for( i = 0; i < len*4; i += 4, dst += dst_step )
1384 t0 = src0[i]; t1 = src0[i+1];
1385 dst[0] = t0; dst[1] = t1;
1386 t0 = src0[i+2]; t1 = src0[i+3];
1387 dst[2] = t0; dst[3] = t1;
1388 t0 = src1[i]; t1 = src1[i+1];
1389 dst[4] = t0; dst[5] = t1;
1390 t0 = src1[i+2]; t1 = src1[i+3];
1391 dst[6] = t0; dst[7] = t1;
1398 ExpandCCS( uchar* _ptr, int n, int elem_size )
1401 if( elem_size == (int)sizeof(float) )
1403 float* p = (float*)_ptr;
1404 for( i = 1; i < (n+1)/2; i++ )
1406 p[(n-i)*2] = p[i*2-1];
1407 p[(n-i)*2+1] = -p[i*2];
1415 for( i = n-1; i > 0; i-- )
1421 double* p = (double*)_ptr;
1422 for( i = 1; i < (n+1)/2; i++ )
1424 p[(n-i)*2] = p[i*2-1];
1425 p[(n-i)*2+1] = -p[i*2];
1433 for( i = n-1; i > 0; i-- )
1440 typedef void (*DFTFunc)(
1441 const void* src, void* dst, int n, int nf, int* factors,
1442 const int* itab, const void* wave, int tab_size,
1443 const void* spec, void* buf, int inv, double scale );
1445 static void DFT_32f( const Complexf* src, Complexf* dst, int n,
1446 int nf, const int* factors, const int* itab,
1447 const Complexf* wave, int tab_size,
1448 const void* spec, Complexf* buf,
1449 int flags, double scale )
1451 DFT(src, dst, n, nf, factors, itab, wave, tab_size, spec, buf, flags, scale);
1454 static void DFT_64f( const Complexd* src, Complexd* dst, int n,
1455 int nf, const int* factors, const int* itab,
1456 const Complexd* wave, int tab_size,
1457 const void* spec, Complexd* buf,
1458 int flags, double scale )
1460 DFT(src, dst, n, nf, factors, itab, wave, tab_size, spec, buf, flags, scale);
1464 static void RealDFT_32f( const float* src, float* dst, int n, int nf, int* factors,
1465 const int* itab, const Complexf* wave, int tab_size, const void* spec,
1466 Complexf* buf, int flags, double scale )
1468 RealDFT( src, dst, n, nf, factors, itab, wave, tab_size, spec, buf, flags, scale);
1471 static void RealDFT_64f( const double* src, double* dst, int n, int nf, int* factors,
1472 const int* itab, const Complexd* wave, int tab_size, const void* spec,
1473 Complexd* buf, int flags, double scale )
1475 RealDFT( src, dst, n, nf, factors, itab, wave, tab_size, spec, buf, flags, scale);
1478 static void CCSIDFT_32f( const float* src, float* dst, int n, int nf, int* factors,
1479 const int* itab, const Complexf* wave, int tab_size, const void* spec,
1480 Complexf* buf, int flags, double scale )
1482 CCSIDFT( src, dst, n, nf, factors, itab, wave, tab_size, spec, buf, flags, scale);
1485 static void CCSIDFT_64f( const double* src, double* dst, int n, int nf, int* factors,
1486 const int* itab, const Complexd* wave, int tab_size, const void* spec,
1487 Complexd* buf, int flags, double scale )
1489 CCSIDFT( src, dst, n, nf, factors, itab, wave, tab_size, spec, buf, flags, scale);
1495 typedef IppStatus (CV_STDCALL* IppDFTGetSizeFunc)(int, int, IppHintAlgorithm, int*, int*, int*);
1496 typedef IppStatus (CV_STDCALL* IppDFTInitFunc)(int, int, IppHintAlgorithm, void*, uchar*);
1501 #if defined USE_IPP_DFT
1503 typedef IppStatus (CV_STDCALL* ippiDFT_C_Func)(const Ipp32fc*, int, Ipp32fc*, int, const IppiDFTSpec_C_32fc*, Ipp8u*);
1504 typedef IppStatus (CV_STDCALL* ippiDFT_R_Func)(const Ipp32f* , int, Ipp32f* , int, const IppiDFTSpec_R_32f* , Ipp8u*);
1506 template <typename Dft>
1507 class Dft_C_IPPLoop_Invoker : public ParallelLoopBody
1511 Dft_C_IPPLoop_Invoker(const Mat& _src, Mat& _dst, const Dft& _ippidft, int _norm_flag, bool *_ok) :
1512 ParallelLoopBody(), src(_src), dst(_dst), ippidft(_ippidft), norm_flag(_norm_flag), ok(_ok)
1517 virtual void operator()(const Range& range) const
1526 IppiSize srcRoiSize = {src.cols, 1};
1528 status = ippiDFTGetSize_C_32fc(srcRoiSize, norm_flag, ippAlgHintNone, &sizeSpec, &sizeInit, &sizeBuffer );
1535 IppiDFTSpec_C_32fc* pDFTSpec = (IppiDFTSpec_C_32fc*)ippMalloc( sizeSpec );
1538 pMemInit = (Ipp8u*)ippMalloc( sizeInit );
1540 if ( sizeBuffer > 0 )
1541 pBuffer = (Ipp8u*)ippMalloc( sizeBuffer );
1543 status = ippiDFTInit_C_32fc( srcRoiSize, norm_flag, ippAlgHintNone, pDFTSpec, pMemInit );
1546 ippFree( pMemInit );
1550 ippFree( pDFTSpec );
1551 if ( sizeBuffer > 0 )
1557 for( int i = range.start; i < range.end; ++i)
1558 if(!ippidft(src.ptr<Ipp32fc>(i), (int)src.step,dst.ptr<Ipp32fc>(i), (int)dst.step, pDFTSpec, (Ipp8u*)pBuffer))
1563 if ( sizeBuffer > 0 )
1566 ippFree( pDFTSpec );
1567 CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT);
1577 const Dft_C_IPPLoop_Invoker& operator= (const Dft_C_IPPLoop_Invoker&);
1580 template <typename Dft>
1581 class Dft_R_IPPLoop_Invoker : public ParallelLoopBody
1585 Dft_R_IPPLoop_Invoker(const Mat& _src, Mat& _dst, const Dft& _ippidft, int _norm_flag, bool *_ok) :
1586 ParallelLoopBody(), src(_src), dst(_dst), ippidft(_ippidft), norm_flag(_norm_flag), ok(_ok)
1591 virtual void operator()(const Range& range) const
1600 IppiSize srcRoiSize = {src.cols, 1};
1602 status = ippiDFTGetSize_R_32f(srcRoiSize, norm_flag, ippAlgHintNone, &sizeSpec, &sizeInit, &sizeBuffer );
1609 IppiDFTSpec_R_32f* pDFTSpec = (IppiDFTSpec_R_32f*)ippMalloc( sizeSpec );
1612 pMemInit = (Ipp8u*)ippMalloc( sizeInit );
1614 if ( sizeBuffer > 0 )
1615 pBuffer = (Ipp8u*)ippMalloc( sizeBuffer );
1617 status = ippiDFTInit_R_32f( srcRoiSize, norm_flag, ippAlgHintNone, pDFTSpec, pMemInit );
1620 ippFree( pMemInit );
1624 ippFree( pDFTSpec );
1625 if ( sizeBuffer > 0 )
1631 for( int i = range.start; i < range.end; ++i)
1632 if(!ippidft(src.ptr<float>(i), (int)src.step,dst.ptr<float>(i), (int)dst.step, pDFTSpec, (Ipp8u*)pBuffer))
1637 if ( sizeBuffer > 0 )
1640 ippFree( pDFTSpec );
1641 CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT);
1651 const Dft_R_IPPLoop_Invoker& operator= (const Dft_R_IPPLoop_Invoker&);
1654 template <typename Dft>
1655 bool Dft_C_IPPLoop(const Mat& src, Mat& dst, const Dft& ippidft, int norm_flag)
1658 parallel_for_(Range(0, src.rows), Dft_C_IPPLoop_Invoker<Dft>(src, dst, ippidft, norm_flag, &ok), src.total()/(double)(1<<16) );
1662 template <typename Dft>
1663 bool Dft_R_IPPLoop(const Mat& src, Mat& dst, const Dft& ippidft, int norm_flag)
1666 parallel_for_(Range(0, src.rows), Dft_R_IPPLoop_Invoker<Dft>(src, dst, ippidft, norm_flag, &ok), src.total()/(double)(1<<16) );
1670 struct IPPDFT_C_Functor
1672 IPPDFT_C_Functor(ippiDFT_C_Func _func) : func(_func){}
1674 bool operator()(const Ipp32fc* src, int srcStep, Ipp32fc* dst, int dstStep, const IppiDFTSpec_C_32fc* pDFTSpec, Ipp8u* pBuffer) const
1676 return func ? func(src, srcStep, dst, dstStep, pDFTSpec, pBuffer) >= 0 : false;
1679 ippiDFT_C_Func func;
1682 struct IPPDFT_R_Functor
1684 IPPDFT_R_Functor(ippiDFT_R_Func _func) : func(_func){}
1686 bool operator()(const Ipp32f* src, int srcStep, Ipp32f* dst, int dstStep, const IppiDFTSpec_R_32f* pDFTSpec, Ipp8u* pBuffer) const
1688 return func ? func(src, srcStep, dst, dstStep, pDFTSpec, pBuffer) >= 0 : false;
1691 ippiDFT_R_Func func;
1694 static bool ippi_DFT_C_32F(const Mat& src, Mat& dst, bool inv, int norm_flag)
1703 IppiSize srcRoiSize = {src.cols, src.rows};
1705 status = ippiDFTGetSize_C_32fc(srcRoiSize, norm_flag, ippAlgHintNone, &sizeSpec, &sizeInit, &sizeBuffer );
1709 IppiDFTSpec_C_32fc* pDFTSpec = (IppiDFTSpec_C_32fc*)ippMalloc( sizeSpec );
1712 pMemInit = (Ipp8u*)ippMalloc( sizeInit );
1714 if ( sizeBuffer > 0 )
1715 pBuffer = (Ipp8u*)ippMalloc( sizeBuffer );
1717 status = ippiDFTInit_C_32fc( srcRoiSize, norm_flag, ippAlgHintNone, pDFTSpec, pMemInit );
1720 ippFree( pMemInit );
1724 ippFree( pDFTSpec );
1725 if ( sizeBuffer > 0 )
1731 status = ippiDFTFwd_CToC_32fc_C1R( src.ptr<Ipp32fc>(), (int)src.step, dst.ptr<Ipp32fc>(), (int)dst.step, pDFTSpec, pBuffer );
1733 status = ippiDFTInv_CToC_32fc_C1R( src.ptr<Ipp32fc>(), (int)src.step, dst.ptr<Ipp32fc>(), (int)dst.step, pDFTSpec, pBuffer );
1735 if ( sizeBuffer > 0 )
1738 ippFree( pDFTSpec );
1742 CV_IMPL_ADD(CV_IMPL_IPP);
1748 static bool ippi_DFT_R_32F(const Mat& src, Mat& dst, bool inv, int norm_flag)
1757 IppiSize srcRoiSize = {src.cols, src.rows};
1759 status = ippiDFTGetSize_R_32f(srcRoiSize, norm_flag, ippAlgHintNone, &sizeSpec, &sizeInit, &sizeBuffer );
1763 IppiDFTSpec_R_32f* pDFTSpec = (IppiDFTSpec_R_32f*)ippMalloc( sizeSpec );
1766 pMemInit = (Ipp8u*)ippMalloc( sizeInit );
1768 if ( sizeBuffer > 0 )
1769 pBuffer = (Ipp8u*)ippMalloc( sizeBuffer );
1771 status = ippiDFTInit_R_32f( srcRoiSize, norm_flag, ippAlgHintNone, pDFTSpec, pMemInit );
1774 ippFree( pMemInit );
1778 ippFree( pDFTSpec );
1779 if ( sizeBuffer > 0 )
1785 status = ippiDFTFwd_RToPack_32f_C1R( src.ptr<float>(), (int)(src.step), dst.ptr<float>(), (int)dst.step, pDFTSpec, pBuffer );
1787 status = ippiDFTInv_PackToR_32f_C1R( src.ptr<float>(), (int)src.step, dst.ptr<float>(), (int)dst.step, pDFTSpec, pBuffer );
1789 if ( sizeBuffer > 0 )
1792 ippFree( pDFTSpec );
1796 CV_IMPL_ADD(CV_IMPL_IPP);
1812 R2R = 0, // real to CCS in case forward transform, CCS to real otherwise
1813 C2R = 1, // complex to real in case inverse transform
1814 R2C = 2, // real to complex in case forward transform
1815 C2C = 3 // complex to complex
1822 String buildOptions;
1829 OCL_FftPlan(int _size, int _depth) : dft_size(_size), dft_depth(_depth), status(true)
1831 CV_Assert( dft_depth == CV_32F || dft_depth == CV_64F );
1834 std::vector<int> radixes, blocks;
1835 ocl_getRadixes(dft_size, radixes, blocks, min_radix);
1836 thread_count = dft_size / min_radix;
1838 if (thread_count > (int) ocl::Device::getDefault().maxWorkGroupSize())
1844 // generate string with radix calls
1845 String radix_processing;
1846 int n = 1, twiddle_size = 0;
1847 for (size_t i=0; i<radixes.size(); i++)
1849 int radix = radixes[i], block = blocks[i];
1851 radix_processing += format("fft_radix%d_B%d(smem,twiddles+%d,ind,%d,%d);", radix, block, twiddle_size, n, dft_size/radix);
1853 radix_processing += format("fft_radix%d(smem,twiddles+%d,ind,%d,%d);", radix, twiddle_size, n, dft_size/radix);
1854 twiddle_size += (radix-1)*n;
1858 twiddles.create(1, twiddle_size, CV_MAKE_TYPE(dft_depth, 2));
1859 if (dft_depth == CV_32F)
1860 fillRadixTable<float>(twiddles, radixes);
1862 fillRadixTable<double>(twiddles, radixes);
1864 buildOptions = format("-D LOCAL_SIZE=%d -D kercn=%d -D FT=%s -D CT=%s%s -D RADIX_PROCESS=%s",
1865 dft_size, min_radix, ocl::typeToStr(dft_depth), ocl::typeToStr(CV_MAKE_TYPE(dft_depth, 2)),
1866 dft_depth == CV_64F ? " -D DOUBLE_SUPPORT" : "", radix_processing.c_str());
1869 bool enqueueTransform(InputArray _src, OutputArray _dst, int num_dfts, int flags, int fftType, bool rows = true) const
1874 UMat src = _src.getUMat();
1875 UMat dst = _dst.getUMat();
1877 size_t globalsize[2];
1878 size_t localsize[2];
1881 bool is1d = (flags & DFT_ROWS) != 0 || num_dfts == 1;
1882 bool inv = (flags & DFT_INVERSE) != 0;
1883 String options = buildOptions;
1887 globalsize[0] = thread_count; globalsize[1] = src.rows;
1888 localsize[0] = thread_count; localsize[1] = 1;
1889 kernel_name = !inv ? "fft_multi_radix_rows" : "ifft_multi_radix_rows";
1890 if ((is1d || inv) && (flags & DFT_SCALE))
1891 options += " -D DFT_SCALE";
1895 globalsize[0] = num_dfts; globalsize[1] = thread_count;
1896 localsize[0] = 1; localsize[1] = thread_count;
1897 kernel_name = !inv ? "fft_multi_radix_cols" : "ifft_multi_radix_cols";
1898 if (flags & DFT_SCALE)
1899 options += " -D DFT_SCALE";
1902 options += src.channels() == 1 ? " -D REAL_INPUT" : " -D COMPLEX_INPUT";
1903 options += dst.channels() == 1 ? " -D REAL_OUTPUT" : " -D COMPLEX_OUTPUT";
1904 options += is1d ? " -D IS_1D" : "";
1908 if ((is1d && src.channels() == 1) || (rows && (fftType == R2R)))
1909 options += " -D NO_CONJUGATE";
1913 if (rows && (fftType == C2R || fftType == R2R))
1914 options += " -D NO_CONJUGATE";
1915 if (dst.cols % 2 == 0)
1916 options += " -D EVEN";
1919 ocl::Kernel k(kernel_name.c_str(), ocl::core::fft_oclsrc, options);
1923 k.args(ocl::KernelArg::ReadOnly(src), ocl::KernelArg::WriteOnly(dst), ocl::KernelArg::ReadOnlyNoSize(twiddles), thread_count, num_dfts);
1924 return k.run(2, globalsize, localsize, false);
1928 static void ocl_getRadixes(int cols, std::vector<int>& radixes, std::vector<int>& blocks, int& min_radix)
1931 int nf = DFTFactorize(cols, factors);
1934 int factor_index = 0;
1935 min_radix = INT_MAX;
1938 if ((factors[factor_index] & 1) == 0)
1940 for( ; n < factors[factor_index];)
1942 int radix = 2, block = 1;
1943 if (8*n <= factors[0])
1945 else if (4*n <= factors[0])
1950 else if (cols % 8 == 0)
1957 else if (cols % 8 == 0)
1959 else if (cols % 6 == 0)
1961 else if (cols % 4 == 0)
1965 radixes.push_back(radix);
1966 blocks.push_back(block);
1967 min_radix = min(min_radix, block*radix);
1973 // all the other transforms
1974 for( ; factor_index < nf; factor_index++)
1976 int radix = factors[factor_index], block = 1;
1981 else if (cols % 9 == 0)
1983 else if (cols % 6 == 0)
1986 else if (radix == 5)
1991 radixes.push_back(radix);
1992 blocks.push_back(block);
1993 min_radix = min(min_radix, block*radix);
1997 template <typename T>
1998 static void fillRadixTable(UMat twiddles, const std::vector<int>& radixes)
2000 Mat tw = twiddles.getMat(ACCESS_WRITE);
2001 T* ptr = tw.ptr<T>();
2005 for (size_t i=0; i<radixes.size(); i++)
2007 int radix = radixes[i];
2010 for (int j=1; j<radix; j++)
2012 double theta = -CV_2PI*j/n;
2014 for (int k=0; k<(n/radix); k++)
2016 ptr[ptr_index++] = (T) cos(k*theta);
2017 ptr[ptr_index++] = (T) sin(k*theta);
2024 class OCL_FftPlanCache
2027 static OCL_FftPlanCache & getInstance()
2029 static OCL_FftPlanCache planCache;
2033 Ptr<OCL_FftPlan> getFftPlan(int dft_size, int depth)
2035 int key = (dft_size << 16) | (depth & 0xFFFF);
2036 std::map<int, Ptr<OCL_FftPlan> >::iterator f = planStorage.find(key);
2037 if (f != planStorage.end())
2043 Ptr<OCL_FftPlan> newPlan = Ptr<OCL_FftPlan>(new OCL_FftPlan(dft_size, depth));
2044 planStorage[key] = newPlan;
2051 planStorage.clear();
2055 OCL_FftPlanCache() :
2059 std::map<int, Ptr<OCL_FftPlan> > planStorage;
2062 static bool ocl_dft_rows(InputArray _src, OutputArray _dst, int nonzero_rows, int flags, int fftType)
2064 int type = _src.type(), depth = CV_MAT_DEPTH(type);
2065 Ptr<OCL_FftPlan> plan = OCL_FftPlanCache::getInstance().getFftPlan(_src.cols(), depth);
2066 return plan->enqueueTransform(_src, _dst, nonzero_rows, flags, fftType, true);
2069 static bool ocl_dft_cols(InputArray _src, OutputArray _dst, int nonzero_cols, int flags, int fftType)
2071 int type = _src.type(), depth = CV_MAT_DEPTH(type);
2072 Ptr<OCL_FftPlan> plan = OCL_FftPlanCache::getInstance().getFftPlan(_src.rows(), depth);
2073 return plan->enqueueTransform(_src, _dst, nonzero_cols, flags, fftType, false);
2076 static bool ocl_dft(InputArray _src, OutputArray _dst, int flags, int nonzero_rows)
2078 int type = _src.type(), cn = CV_MAT_CN(type), depth = CV_MAT_DEPTH(type);
2079 Size ssize = _src.size();
2080 bool doubleSupport = ocl::Device::getDefault().doubleFPConfig() > 0;
2082 if ( !((cn == 1 || cn == 2) && (depth == CV_32F || (depth == CV_64F && doubleSupport))) )
2085 // if is not a multiplication of prime numbers { 2, 3, 5 }
2086 if (ssize.area() != getOptimalDFTSize(ssize.area()))
2089 UMat src = _src.getUMat();
2090 int complex_input = cn == 2 ? 1 : 0;
2091 int complex_output = (flags & DFT_COMPLEX_OUTPUT) != 0;
2092 int real_input = cn == 1 ? 1 : 0;
2093 int real_output = (flags & DFT_REAL_OUTPUT) != 0;
2094 bool inv = (flags & DFT_INVERSE) != 0 ? 1 : 0;
2096 if( nonzero_rows <= 0 || nonzero_rows > _src.rows() )
2097 nonzero_rows = _src.rows();
2098 bool is1d = (flags & DFT_ROWS) != 0 || nonzero_rows == 1;
2100 // if output format is not specified
2101 if (complex_output + real_output == 0)
2109 FftType fftType = (FftType)(complex_input << 0 | complex_output << 1);
2111 // Forward Complex to CCS not supported
2112 if (fftType == C2R && !inv)
2115 // Inverse CCS to Complex not supported
2116 if (fftType == R2C && inv)
2120 if (fftType == C2C || fftType == R2C)
2123 _dst.create(src.size(), CV_MAKETYPE(depth, 2));
2124 output = _dst.getUMat();
2131 _dst.create(src.size(), CV_MAKETYPE(depth, 1));
2132 output = _dst.getUMat();
2136 _dst.create(src.size(), CV_MAKETYPE(depth, 1));
2137 output.create(src.size(), CV_MAKETYPE(depth, 2));
2143 if (!ocl_dft_rows(src, output, nonzero_rows, flags, fftType))
2148 int nonzero_cols = fftType == R2R ? output.cols/2 + 1 : output.cols;
2149 if (!ocl_dft_cols(output, _dst, nonzero_cols, flags, fftType))
2158 if (!ocl_dft_rows(src, output, nonzero_rows, flags, fftType))
2163 if (!ocl_dft_cols(output, output, output.cols, flags, fftType))
2171 if (!ocl_dft_rows(src, output, nonzero_rows, flags, fftType))
2176 int nonzero_cols = src.cols/2 + 1;
2177 if (!ocl_dft_cols(src, output, nonzero_cols, flags, fftType))
2180 if (!ocl_dft_rows(output, _dst, nonzero_rows, flags, fftType))
2192 #ifdef HAVE_CLAMDFFT
2196 #define CLAMDDFT_Assert(func) \
2198 clAmdFftStatus s = (func); \
2199 CV_Assert(s == CLFFT_SUCCESS); \
2206 FftPlan(const Size & _dft_size, int _src_step, int _dst_step, bool _doubleFP, bool _inplace, int _flags, FftType _fftType) :
2207 dft_size(_dft_size), src_step(_src_step), dst_step(_dst_step),
2208 doubleFP(_doubleFP), inplace(_inplace), flags(_flags), fftType(_fftType),
2209 context((cl_context)ocl::Context::getDefault().ptr()), plHandle(0)
2211 bool dft_inverse = (flags & DFT_INVERSE) != 0;
2212 bool dft_scale = (flags & DFT_SCALE) != 0;
2213 bool dft_rows = (flags & DFT_ROWS) != 0;
2215 clAmdFftLayout inLayout = CLFFT_REAL, outLayout = CLFFT_REAL;
2216 clAmdFftDim dim = dft_size.height == 1 || dft_rows ? CLFFT_1D : CLFFT_2D;
2218 size_t batchSize = dft_rows ? dft_size.height : 1;
2219 size_t clLengthsIn[3] = { dft_size.width, dft_rows ? 1 : dft_size.height, 1 };
2220 size_t clStridesIn[3] = { 1, 1, 1 };
2221 size_t clStridesOut[3] = { 1, 1, 1 };
2222 int elemSize = doubleFP ? sizeof(double) : sizeof(float);
2227 inLayout = CLFFT_COMPLEX_INTERLEAVED;
2228 outLayout = CLFFT_COMPLEX_INTERLEAVED;
2229 clStridesIn[1] = src_step / (elemSize << 1);
2230 clStridesOut[1] = dst_step / (elemSize << 1);
2233 inLayout = CLFFT_REAL;
2234 outLayout = CLFFT_HERMITIAN_INTERLEAVED;
2235 clStridesIn[1] = src_step / elemSize;
2236 clStridesOut[1] = dst_step / (elemSize << 1);
2239 inLayout = CLFFT_HERMITIAN_INTERLEAVED;
2240 outLayout = CLFFT_REAL;
2241 clStridesIn[1] = src_step / (elemSize << 1);
2242 clStridesOut[1] = dst_step / elemSize;
2246 CV_Error(Error::StsNotImplemented, "AMD Fft does not support this type");
2250 clStridesIn[2] = dft_rows ? clStridesIn[1] : dft_size.width * clStridesIn[1];
2251 clStridesOut[2] = dft_rows ? clStridesOut[1] : dft_size.width * clStridesOut[1];
2253 CLAMDDFT_Assert(clAmdFftCreateDefaultPlan(&plHandle, (cl_context)ocl::Context::getDefault().ptr(), dim, clLengthsIn))
2255 // setting plan properties
2256 CLAMDDFT_Assert(clAmdFftSetPlanPrecision(plHandle, doubleFP ? CLFFT_DOUBLE : CLFFT_SINGLE));
2257 CLAMDDFT_Assert(clAmdFftSetResultLocation(plHandle, inplace ? CLFFT_INPLACE : CLFFT_OUTOFPLACE))
2258 CLAMDDFT_Assert(clAmdFftSetLayout(plHandle, inLayout, outLayout))
2259 CLAMDDFT_Assert(clAmdFftSetPlanBatchSize(plHandle, batchSize))
2260 CLAMDDFT_Assert(clAmdFftSetPlanInStride(plHandle, dim, clStridesIn))
2261 CLAMDDFT_Assert(clAmdFftSetPlanOutStride(plHandle, dim, clStridesOut))
2262 CLAMDDFT_Assert(clAmdFftSetPlanDistance(plHandle, clStridesIn[dim], clStridesOut[dim]))
2264 float scale = dft_scale ? 1.0f / (dft_rows ? dft_size.width : dft_size.area()) : 1.0f;
2265 CLAMDDFT_Assert(clAmdFftSetPlanScale(plHandle, dft_inverse ? CLFFT_BACKWARD : CLFFT_FORWARD, scale))
2268 cl_command_queue queue = (cl_command_queue)ocl::Queue::getDefault().ptr();
2269 CLAMDDFT_Assert(clAmdFftBakePlan(plHandle, 1, &queue, NULL, NULL))
2274 // clAmdFftDestroyPlan(&plHandle);
2277 friend class PlanCache;
2281 int src_step, dst_step;
2288 clAmdFftPlanHandle plHandle;
2292 static PlanCache & getInstance()
2294 static PlanCache planCache;
2298 clAmdFftPlanHandle getPlanHandle(const Size & dft_size, int src_step, int dst_step, bool doubleFP,
2299 bool inplace, int flags, FftType fftType)
2301 cl_context currentContext = (cl_context)ocl::Context::getDefault().ptr();
2303 for (size_t i = 0, size = planStorage.size(); i < size; ++i)
2305 const FftPlan * const plan = planStorage[i];
2307 if (plan->dft_size == dft_size &&
2308 plan->flags == flags &&
2309 plan->src_step == src_step &&
2310 plan->dst_step == dst_step &&
2311 plan->doubleFP == doubleFP &&
2312 plan->fftType == fftType &&
2313 plan->inplace == inplace)
2315 if (plan->context != currentContext)
2317 planStorage.erase(planStorage.begin() + i);
2321 return plan->plHandle;
2325 // no baked plan is found, so let's create a new one
2326 Ptr<FftPlan> newPlan = Ptr<FftPlan>(new FftPlan(dft_size, src_step, dst_step, doubleFP, inplace, flags, fftType));
2327 planStorage.push_back(newPlan);
2329 return newPlan->plHandle;
2334 planStorage.clear();
2343 std::vector<Ptr<FftPlan> > planStorage;
2348 static void CL_CALLBACK oclCleanupCallback(cl_event e, cl_int, void *p)
2350 UMatData * u = (UMatData *)p;
2352 if( u && CV_XADD(&u->urefcount, -1) == 1 )
2353 u->currAllocator->deallocate(u);
2356 clReleaseEvent(e), e = 0;
2361 static bool ocl_dft_amdfft(InputArray _src, OutputArray _dst, int flags)
2363 int type = _src.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
2364 Size ssize = _src.size();
2366 bool doubleSupport = ocl::Device::getDefault().doubleFPConfig() > 0;
2367 if ( (!doubleSupport && depth == CV_64F) ||
2368 !(type == CV_32FC1 || type == CV_32FC2 || type == CV_64FC1 || type == CV_64FC2) ||
2372 // if is not a multiplication of prime numbers { 2, 3, 5 }
2373 if (ssize.area() != getOptimalDFTSize(ssize.area()))
2376 int dst_complex_input = cn == 2 ? 1 : 0;
2377 bool dft_inverse = (flags & DFT_INVERSE) != 0 ? 1 : 0;
2378 int dft_complex_output = (flags & DFT_COMPLEX_OUTPUT) != 0;
2379 bool dft_real_output = (flags & DFT_REAL_OUTPUT) != 0;
2381 CV_Assert(dft_complex_output + dft_real_output < 2);
2382 FftType fftType = (FftType)(dst_complex_input << 0 | dft_complex_output << 1);
2387 _dst.create(ssize.height, ssize.width, CV_MAKE_TYPE(depth, 2));
2389 case R2C: // TODO implement it if possible
2390 case C2R: // TODO implement it if possible
2391 case R2R: // AMD Fft does not support this type
2396 UMat src = _src.getUMat(), dst = _dst.getUMat();
2397 bool inplace = src.u == dst.u;
2399 clAmdFftPlanHandle plHandle = PlanCache::getInstance().
2400 getPlanHandle(ssize, (int)src.step, (int)dst.step,
2401 depth == CV_64F, inplace, flags, fftType);
2403 // get the bufferSize
2404 size_t bufferSize = 0;
2405 CLAMDDFT_Assert(clAmdFftGetTmpBufSize(plHandle, &bufferSize))
2406 UMat tmpBuffer(1, (int)bufferSize, CV_8UC1);
2408 cl_mem srcarg = (cl_mem)src.handle(ACCESS_READ);
2409 cl_mem dstarg = (cl_mem)dst.handle(ACCESS_RW);
2411 cl_command_queue queue = (cl_command_queue)ocl::Queue::getDefault().ptr();
2414 CLAMDDFT_Assert(clAmdFftEnqueueTransform(plHandle, dft_inverse ? CLFFT_BACKWARD : CLFFT_FORWARD,
2415 1, &queue, 0, NULL, &e,
2416 &srcarg, &dstarg, (cl_mem)tmpBuffer.handle(ACCESS_RW)))
2419 clSetEventCallback(e, CL_COMPLETE, oclCleanupCallback, tmpBuffer.u);
2427 #endif // HAVE_CLAMDFFT
2429 void cv::dft( InputArray _src0, OutputArray _dst, int flags, int nonzero_rows )
2431 #ifdef HAVE_CLAMDFFT
2432 CV_OCL_RUN(ocl::haveAmdFft() && ocl::Device::getDefault().type() != ocl::Device::TYPE_CPU &&
2433 _dst.isUMat() && _src0.dims() <= 2 && nonzero_rows == 0,
2434 ocl_dft_amdfft(_src0, _dst, flags))
2438 CV_OCL_RUN(_dst.isUMat() && _src0.dims() <= 2,
2439 ocl_dft(_src0, _dst, flags, nonzero_rows))
2442 static DFTFunc dft_tbl[6] =
2445 (DFTFunc)RealDFT_32f,
2446 (DFTFunc)CCSIDFT_32f,
2448 (DFTFunc)RealDFT_64f,
2449 (DFTFunc)CCSIDFT_64f
2451 AutoBuffer<uchar> buf;
2453 Mat src0 = _src0.getMat(), src = src0;
2454 int prev_len = 0, stage = 0;
2455 bool inv = (flags & DFT_INVERSE) != 0;
2456 int nf = 0, real_transform = src.channels() == 1 || (inv && (flags & DFT_REAL_OUTPUT)!=0);
2457 int type = src.type(), depth = src.depth();
2458 int elem_size = (int)src.elemSize1(), complex_elem_size = elem_size*2;
2460 bool inplace_transform = false;
2462 AutoBuffer<uchar> ippbuf;
2463 int ipp_norm_flag = !(flags & DFT_SCALE) ? 8 : inv ? 2 : 1;
2466 CV_Assert( type == CV_32FC1 || type == CV_32FC2 || type == CV_64FC1 || type == CV_64FC2 );
2468 if( !inv && src.channels() == 1 && (flags & DFT_COMPLEX_OUTPUT) )
2469 _dst.create( src.size(), CV_MAKETYPE(depth, 2) );
2470 else if( inv && src.channels() == 2 && (flags & DFT_REAL_OUTPUT) )
2471 _dst.create( src.size(), depth );
2473 _dst.create( src.size(), type );
2475 Mat dst = _dst.getMat();
2477 #if defined USE_IPP_DFT
2480 if ((src.depth() == CV_32F) && (src.total()>(int)(1<<6)) && nonzero_rows == 0)
2482 if ((flags & DFT_ROWS) == 0)
2484 if (src.channels() == 2 && !(inv && (flags & DFT_REAL_OUTPUT)))
2486 if (ippi_DFT_C_32F(src, dst, inv, ipp_norm_flag))
2488 CV_IMPL_ADD(CV_IMPL_IPP);
2491 setIppErrorStatus();
2493 if (src.channels() == 1 && (inv || !(flags & DFT_COMPLEX_OUTPUT)))
2495 if (ippi_DFT_R_32F(src, dst, inv, ipp_norm_flag))
2497 CV_IMPL_ADD(CV_IMPL_IPP);
2500 setIppErrorStatus();
2505 if (src.channels() == 2 && !(inv && (flags & DFT_REAL_OUTPUT)))
2507 ippiDFT_C_Func ippiFunc = inv ? (ippiDFT_C_Func)ippiDFTInv_CToC_32fc_C1R : (ippiDFT_C_Func)ippiDFTFwd_CToC_32fc_C1R;
2508 if (Dft_C_IPPLoop(src, dst, IPPDFT_C_Functor(ippiFunc),ipp_norm_flag))
2510 CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT);
2513 setIppErrorStatus();
2515 if (src.channels() == 1 && (inv || !(flags & DFT_COMPLEX_OUTPUT)))
2517 ippiDFT_R_Func ippiFunc = inv ? (ippiDFT_R_Func)ippiDFTInv_PackToR_32f_C1R : (ippiDFT_R_Func)ippiDFTFwd_RToPack_32f_C1R;
2518 if (Dft_R_IPPLoop(src, dst, IPPDFT_R_Functor(ippiFunc),ipp_norm_flag))
2520 CV_IMPL_ADD(CV_IMPL_IPP|CV_IMPL_MT);
2523 setIppErrorStatus();
2530 if( !real_transform )
2531 elem_size = complex_elem_size;
2533 if( src.cols == 1 && nonzero_rows > 0 )
2534 CV_Error( CV_StsNotImplemented,
2535 "This mode (using nonzero_rows with a single-column matrix) breaks the function's logic, so it is prohibited.\n"
2536 "For fast convolution/correlation use 2-column matrix or single-row matrix instead" );
2538 // determine, which transform to do first - row-wise
2539 // (stage 0) or column-wise (stage 1) transform
2540 if( !(flags & DFT_ROWS) && src.rows > 1 &&
2541 ((src.cols == 1 && (!src.isContinuous() || !dst.isContinuous())) ||
2542 (src.cols > 1 && inv && real_transform)) )
2551 int i, len, count, sz = 0;
2552 int use_buf = 0, odd_real = 0;
2555 if( stage == 0 ) // row-wise transform
2557 len = !inv ? src.cols : dst.cols;
2559 if( len == 1 && !(flags & DFT_ROWS) )
2561 len = !inv ? src.rows : dst.rows;
2564 odd_real = real_transform && (len & 1);
2569 count = !inv ? src0.cols : dst.cols;
2570 sz = 2*len*complex_elem_size;
2575 if( CV_IPP_CHECK_COND && (len*count >= 64) ) // use IPP DFT if available
2577 int specsize=0, initsize=0, worksize=0;
2578 IppDFTGetSizeFunc getSizeFunc = 0;
2579 IppDFTInitFunc initFunc = 0;
2581 if( real_transform && stage == 0 )
2583 if( depth == CV_32F )
2585 getSizeFunc = ippsDFTGetSize_R_32f;
2586 initFunc = (IppDFTInitFunc)ippsDFTInit_R_32f;
2590 getSizeFunc = ippsDFTGetSize_R_64f;
2591 initFunc = (IppDFTInitFunc)ippsDFTInit_R_64f;
2596 if( depth == CV_32F )
2598 getSizeFunc = ippsDFTGetSize_C_32fc;
2599 initFunc = (IppDFTInitFunc)ippsDFTInit_C_32fc;
2603 getSizeFunc = ippsDFTGetSize_C_64fc;
2604 initFunc = (IppDFTInitFunc)ippsDFTInit_C_64fc;
2607 if( getSizeFunc(len, ipp_norm_flag, ippAlgHintNone, &specsize, &initsize, &worksize) >= 0 )
2609 ippbuf.allocate(specsize + initsize + 64);
2610 spec = alignPtr(&ippbuf[0], 32);
2611 uchar* initbuf = alignPtr((uchar*)spec + specsize, 32);
2612 if( initFunc(len, ipp_norm_flag, ippAlgHintNone, spec, initbuf) < 0 )
2617 setIppErrorStatus();
2622 if( len != prev_len )
2623 nf = DFTFactorize( len, factors );
2625 inplace_transform = factors[0] == factors[nf-1];
2626 sz += len*(complex_elem_size + sizeof(int));
2627 i = nf > 1 && (factors[0] & 1) == 0;
2628 if( (factors[i] & 1) != 0 && factors[i] > 5 )
2629 sz += (factors[i]+1)*complex_elem_size;
2631 if( (stage == 0 && ((src.data == dst.data && !inplace_transform) || odd_real)) ||
2632 (stage == 1 && !inplace_transform) )
2635 sz += len*complex_elem_size;
2640 buf.allocate( sz + 32 );
2641 if( ptr != (uchar*)buf )
2642 prev_len = 0; // because we release the buffer,
2643 // force recalculation of
2644 // twiddle factors and permutation table
2649 ptr += len*complex_elem_size;
2651 ptr = (uchar*)cvAlignPtr( ptr + len*sizeof(int), 16 );
2653 if( len != prev_len || (!inplace_transform && inv && real_transform))
2654 DFTInit( len, nf, factors, itab, complex_elem_size,
2655 wave, stage == 0 && inv && real_transform );
2656 // otherwise reuse the tables calculated on the previous stage
2662 int dptr_offset = 0;
2663 int dst_full_len = len*elem_size;
2664 int _flags = (int)inv + (src.channels() != dst.channels() ?
2665 DFT_COMPLEX_INPUT_OR_OUTPUT : 0);
2669 ptr += len*complex_elem_size;
2670 if( odd_real && !inv && len > 1 &&
2671 !(_flags & DFT_COMPLEX_INPUT_OR_OUTPUT))
2672 dptr_offset = elem_size;
2675 if( !inv && (_flags & DFT_COMPLEX_INPUT_OR_OUTPUT) )
2676 dst_full_len += (len & 1) ? elem_size : complex_elem_size;
2678 dft_func = dft_tbl[(!real_transform ? 0 : !inv ? 1 : 2) + (depth == CV_64F)*3];
2680 if( count > 1 && !(flags & DFT_ROWS) && (!inv || !real_transform) )
2682 else if( flags & CV_DXT_SCALE )
2683 scale = 1./(len * (flags & DFT_ROWS ? 1 : count));
2685 if( nonzero_rows <= 0 || nonzero_rows > count )
2686 nonzero_rows = count;
2688 for( i = 0; i < nonzero_rows; i++ )
2690 const uchar* sptr = src.ptr(i);
2691 uchar* dptr0 = dst.ptr(i);
2692 uchar* dptr = dptr0;
2697 dft_func( sptr, dptr, len, nf, factors, itab, wave, len, spec, ptr, _flags, scale );
2699 memcpy( dptr0, dptr + dptr_offset, dst_full_len );
2702 for( ; i < count; i++ )
2704 uchar* dptr0 = dst.ptr(i);
2705 memset( dptr0, 0, dst_full_len );
2714 int a = 0, b = count;
2715 uchar *buf0, *buf1, *dbuf0, *dbuf1;
2716 const uchar* sptr0 = src.ptr();
2717 uchar* dptr0 = dst.ptr();
2719 ptr += len*complex_elem_size;
2721 ptr += len*complex_elem_size;
2722 dbuf0 = buf0, dbuf1 = buf1;
2728 ptr += len*complex_elem_size;
2731 dft_func = dft_tbl[(depth == CV_64F)*3];
2733 if( real_transform && inv && src.cols > 1 )
2735 else if( flags & CV_DXT_SCALE )
2736 scale = 1./(len * count);
2738 if( real_transform )
2742 even = (count & 1) == 0;
2746 memset( buf0, 0, len*complex_elem_size );
2747 CopyColumn( sptr0, src.step, buf0, complex_elem_size, len, elem_size );
2748 sptr0 += dst.channels()*elem_size;
2751 memset( buf1, 0, len*complex_elem_size );
2752 CopyColumn( sptr0 + (count-2)*elem_size, src.step,
2753 buf1, complex_elem_size, len, elem_size );
2756 else if( src.channels() == 1 )
2758 CopyColumn( sptr0, src.step, buf0, elem_size, len, elem_size );
2759 ExpandCCS( buf0, len, elem_size );
2762 CopyColumn( sptr0 + (count-1)*elem_size, src.step,
2763 buf1, elem_size, len, elem_size );
2764 ExpandCCS( buf1, len, elem_size );
2770 CopyColumn( sptr0, src.step, buf0, complex_elem_size, len, complex_elem_size );
2773 CopyColumn( sptr0 + b*complex_elem_size, src.step,
2774 buf1, complex_elem_size, len, complex_elem_size );
2776 sptr0 += complex_elem_size;
2780 dft_func( buf1, dbuf1, len, nf, factors, itab,
2781 wave, len, spec, ptr, inv, scale );
2782 dft_func( buf0, dbuf0, len, nf, factors, itab,
2783 wave, len, spec, ptr, inv, scale );
2785 if( dst.channels() == 1 )
2789 // copy the half of output vector to the first/last column.
2790 // before doing that, defgragment the vector
2791 memcpy( dbuf0 + elem_size, dbuf0, elem_size );
2792 CopyColumn( dbuf0 + elem_size, elem_size, dptr0,
2793 dst.step, len, elem_size );
2796 memcpy( dbuf1 + elem_size, dbuf1, elem_size );
2797 CopyColumn( dbuf1 + elem_size, elem_size,
2798 dptr0 + (count-1)*elem_size,
2799 dst.step, len, elem_size );
2805 // copy the real part of the complex vector to the first/last column
2806 CopyColumn( dbuf0, complex_elem_size, dptr0, dst.step, len, elem_size );
2808 CopyColumn( dbuf1, complex_elem_size, dptr0 + (count-1)*elem_size,
2809 dst.step, len, elem_size );
2816 CopyColumn( dbuf0, complex_elem_size, dptr0,
2817 dst.step, len, complex_elem_size );
2819 CopyColumn( dbuf1, complex_elem_size,
2820 dptr0 + b*complex_elem_size,
2821 dst.step, len, complex_elem_size );
2822 dptr0 += complex_elem_size;
2826 for( i = a; i < b; i += 2 )
2830 CopyFrom2Columns( sptr0, src.step, buf0, buf1, len, complex_elem_size );
2831 dft_func( buf1, dbuf1, len, nf, factors, itab,
2832 wave, len, spec, ptr, inv, scale );
2835 CopyColumn( sptr0, src.step, buf0, complex_elem_size, len, complex_elem_size );
2837 dft_func( buf0, dbuf0, len, nf, factors, itab,
2838 wave, len, spec, ptr, inv, scale );
2841 CopyTo2Columns( dbuf0, dbuf1, dptr0, dst.step, len, complex_elem_size );
2843 CopyColumn( dbuf0, complex_elem_size, dptr0, dst.step, len, complex_elem_size );
2844 sptr0 += 2*complex_elem_size;
2845 dptr0 += 2*complex_elem_size;
2850 if( !inv && real_transform && dst.channels() == 2 && len > 1 )
2853 if( elem_size == (int)sizeof(float) )
2855 float* p0 = dst.ptr<float>();
2856 size_t dstep = dst.step/sizeof(p0[0]);
2857 for( i = 0; i < len; i++ )
2859 float* p = p0 + dstep*i;
2860 float* q = i == 0 || i*2 == len ? p : p0 + dstep*(len-i);
2862 for( int j = 1; j < (n+1)/2; j++ )
2864 p[(n-j)*2] = q[j*2];
2865 p[(n-j)*2+1] = -q[j*2+1];
2871 double* p0 = dst.ptr<double>();
2872 size_t dstep = dst.step/sizeof(p0[0]);
2873 for( i = 0; i < len; i++ )
2875 double* p = p0 + dstep*i;
2876 double* q = i == 0 || i*2 == len ? p : p0 + dstep*(len-i);
2878 for( int j = 1; j < (n+1)/2; j++ )
2880 p[(n-j)*2] = q[j*2];
2881 p[(n-j)*2+1] = -q[j*2+1];
2894 void cv::idft( InputArray src, OutputArray dst, int flags, int nonzero_rows )
2896 dft( src, dst, flags | DFT_INVERSE, nonzero_rows );
2903 static bool ocl_mulSpectrums( InputArray _srcA, InputArray _srcB,
2904 OutputArray _dst, int flags, bool conjB )
2906 int atype = _srcA.type(), btype = _srcB.type(),
2907 rowsPerWI = ocl::Device::getDefault().isIntel() ? 4 : 1;
2908 Size asize = _srcA.size(), bsize = _srcB.size();
2909 CV_Assert(asize == bsize);
2911 if ( !(atype == CV_32FC2 && btype == CV_32FC2) || flags != 0 )
2914 UMat A = _srcA.getUMat(), B = _srcB.getUMat();
2915 CV_Assert(A.size() == B.size());
2917 _dst.create(A.size(), atype);
2918 UMat dst = _dst.getUMat();
2920 ocl::Kernel k("mulAndScaleSpectrums",
2921 ocl::core::mulspectrums_oclsrc,
2922 format("%s", conjB ? "-D CONJ" : ""));
2926 k.args(ocl::KernelArg::ReadOnlyNoSize(A), ocl::KernelArg::ReadOnlyNoSize(B),
2927 ocl::KernelArg::WriteOnly(dst), rowsPerWI);
2929 size_t globalsize[2] = { asize.width, (asize.height + rowsPerWI - 1) / rowsPerWI };
2930 return k.run(2, globalsize, NULL, false);
2937 void cv::mulSpectrums( InputArray _srcA, InputArray _srcB,
2938 OutputArray _dst, int flags, bool conjB )
2940 CV_OCL_RUN(_dst.isUMat() && _srcA.dims() <= 2 && _srcB.dims() <= 2,
2941 ocl_mulSpectrums(_srcA, _srcB, _dst, flags, conjB))
2943 Mat srcA = _srcA.getMat(), srcB = _srcB.getMat();
2944 int depth = srcA.depth(), cn = srcA.channels(), type = srcA.type();
2945 int rows = srcA.rows, cols = srcA.cols;
2948 CV_Assert( type == srcB.type() && srcA.size() == srcB.size() );
2949 CV_Assert( type == CV_32FC1 || type == CV_32FC2 || type == CV_64FC1 || type == CV_64FC2 );
2951 _dst.create( srcA.rows, srcA.cols, type );
2952 Mat dst = _dst.getMat();
2954 bool is_1d = (flags & DFT_ROWS) || (rows == 1 || (cols == 1 &&
2955 srcA.isContinuous() && srcB.isContinuous() && dst.isContinuous()));
2957 if( is_1d && !(flags & DFT_ROWS) )
2958 cols = cols + rows - 1, rows = 1;
2960 int ncols = cols*cn;
2962 int j1 = ncols - (cols % 2 == 0 && cn == 1);
2964 if( depth == CV_32F )
2966 const float* dataA = srcA.ptr<float>();
2967 const float* dataB = srcB.ptr<float>();
2968 float* dataC = dst.ptr<float>();
2970 size_t stepA = srcA.step/sizeof(dataA[0]);
2971 size_t stepB = srcB.step/sizeof(dataB[0]);
2972 size_t stepC = dst.step/sizeof(dataC[0]);
2974 if( !is_1d && cn == 1 )
2976 for( k = 0; k < (cols % 2 ? 1 : 2); k++ )
2979 dataA += cols - 1, dataB += cols - 1, dataC += cols - 1;
2980 dataC[0] = dataA[0]*dataB[0];
2982 dataC[(rows-1)*stepC] = dataA[(rows-1)*stepA]*dataB[(rows-1)*stepB];
2984 for( j = 1; j <= rows - 2; j += 2 )
2986 double re = (double)dataA[j*stepA]*dataB[j*stepB] -
2987 (double)dataA[(j+1)*stepA]*dataB[(j+1)*stepB];
2988 double im = (double)dataA[j*stepA]*dataB[(j+1)*stepB] +
2989 (double)dataA[(j+1)*stepA]*dataB[j*stepB];
2990 dataC[j*stepC] = (float)re; dataC[(j+1)*stepC] = (float)im;
2993 for( j = 1; j <= rows - 2; j += 2 )
2995 double re = (double)dataA[j*stepA]*dataB[j*stepB] +
2996 (double)dataA[(j+1)*stepA]*dataB[(j+1)*stepB];
2997 double im = (double)dataA[(j+1)*stepA]*dataB[j*stepB] -
2998 (double)dataA[j*stepA]*dataB[(j+1)*stepB];
2999 dataC[j*stepC] = (float)re; dataC[(j+1)*stepC] = (float)im;
3002 dataA -= cols - 1, dataB -= cols - 1, dataC -= cols - 1;
3006 for( ; rows--; dataA += stepA, dataB += stepB, dataC += stepC )
3008 if( is_1d && cn == 1 )
3010 dataC[0] = dataA[0]*dataB[0];
3012 dataC[j1] = dataA[j1]*dataB[j1];
3016 for( j = j0; j < j1; j += 2 )
3018 double re = (double)dataA[j]*dataB[j] - (double)dataA[j+1]*dataB[j+1];
3019 double im = (double)dataA[j+1]*dataB[j] + (double)dataA[j]*dataB[j+1];
3020 dataC[j] = (float)re; dataC[j+1] = (float)im;
3023 for( j = j0; j < j1; j += 2 )
3025 double re = (double)dataA[j]*dataB[j] + (double)dataA[j+1]*dataB[j+1];
3026 double im = (double)dataA[j+1]*dataB[j] - (double)dataA[j]*dataB[j+1];
3027 dataC[j] = (float)re; dataC[j+1] = (float)im;
3033 const double* dataA = srcA.ptr<double>();
3034 const double* dataB = srcB.ptr<double>();
3035 double* dataC = dst.ptr<double>();
3037 size_t stepA = srcA.step/sizeof(dataA[0]);
3038 size_t stepB = srcB.step/sizeof(dataB[0]);
3039 size_t stepC = dst.step/sizeof(dataC[0]);
3041 if( !is_1d && cn == 1 )
3043 for( k = 0; k < (cols % 2 ? 1 : 2); k++ )
3046 dataA += cols - 1, dataB += cols - 1, dataC += cols - 1;
3047 dataC[0] = dataA[0]*dataB[0];
3049 dataC[(rows-1)*stepC] = dataA[(rows-1)*stepA]*dataB[(rows-1)*stepB];
3051 for( j = 1; j <= rows - 2; j += 2 )
3053 double re = dataA[j*stepA]*dataB[j*stepB] -
3054 dataA[(j+1)*stepA]*dataB[(j+1)*stepB];
3055 double im = dataA[j*stepA]*dataB[(j+1)*stepB] +
3056 dataA[(j+1)*stepA]*dataB[j*stepB];
3057 dataC[j*stepC] = re; dataC[(j+1)*stepC] = im;
3060 for( j = 1; j <= rows - 2; j += 2 )
3062 double re = dataA[j*stepA]*dataB[j*stepB] +
3063 dataA[(j+1)*stepA]*dataB[(j+1)*stepB];
3064 double im = dataA[(j+1)*stepA]*dataB[j*stepB] -
3065 dataA[j*stepA]*dataB[(j+1)*stepB];
3066 dataC[j*stepC] = re; dataC[(j+1)*stepC] = im;
3069 dataA -= cols - 1, dataB -= cols - 1, dataC -= cols - 1;
3073 for( ; rows--; dataA += stepA, dataB += stepB, dataC += stepC )
3075 if( is_1d && cn == 1 )
3077 dataC[0] = dataA[0]*dataB[0];
3079 dataC[j1] = dataA[j1]*dataB[j1];
3083 for( j = j0; j < j1; j += 2 )
3085 double re = dataA[j]*dataB[j] - dataA[j+1]*dataB[j+1];
3086 double im = dataA[j+1]*dataB[j] + dataA[j]*dataB[j+1];
3087 dataC[j] = re; dataC[j+1] = im;
3090 for( j = j0; j < j1; j += 2 )
3092 double re = dataA[j]*dataB[j] + dataA[j+1]*dataB[j+1];
3093 double im = dataA[j+1]*dataB[j] - dataA[j]*dataB[j+1];
3094 dataC[j] = re; dataC[j+1] = im;
3101 /****************************************************************************************\
3102 Discrete Cosine Transform
3103 \****************************************************************************************/
3108 /* DCT is calculated using DFT, as described here:
3109 http://www.ece.utexas.edu/~bevans/courses/ee381k/lectures/09_DCT/lecture9/:
3111 template<typename T> static void
3112 DCT( const T* src, int src_step, T* dft_src, T* dft_dst, T* dst, int dst_step,
3113 int n, int nf, int* factors, const int* itab, const Complex<T>* dft_wave,
3114 const Complex<T>* dct_wave, const void* spec, Complex<T>* buf )
3116 static const T sin_45 = (T)0.70710678118654752440084436210485;
3119 src_step /= sizeof(src[0]);
3120 dst_step /= sizeof(dst[0]);
3121 T* dst1 = dst + (n-1)*dst_step;
3129 for( j = 0; j < n2; j++, src += src_step*2 )
3131 dft_src[j] = src[0];
3132 dft_src[n-j-1] = src[src_step];
3135 RealDFT( dft_src, dft_dst, n, nf, factors,
3136 itab, dft_wave, n, spec, buf, 0, 1.0 );
3139 dst[0] = (T)(src[0]*dct_wave->re*sin_45);
3141 for( j = 1, dct_wave++; j < n2; j++, dct_wave++,
3142 dst += dst_step, dst1 -= dst_step )
3144 T t0 = dct_wave->re*src[j*2-1] - dct_wave->im*src[j*2];
3145 T t1 = -dct_wave->im*src[j*2-1] - dct_wave->re*src[j*2];
3150 dst[0] = src[n-1]*dct_wave->re;
3154 template<typename T> static void
3155 IDCT( const T* src, int src_step, T* dft_src, T* dft_dst, T* dst, int dst_step,
3156 int n, int nf, int* factors, const int* itab, const Complex<T>* dft_wave,
3157 const Complex<T>* dct_wave, const void* spec, Complex<T>* buf )
3159 static const T sin_45 = (T)0.70710678118654752440084436210485;
3162 src_step /= sizeof(src[0]);
3163 dst_step /= sizeof(dst[0]);
3164 const T* src1 = src + (n-1)*src_step;
3172 dft_src[0] = (T)(src[0]*2*dct_wave->re*sin_45);
3174 for( j = 1, dct_wave++; j < n2; j++, dct_wave++,
3175 src += src_step, src1 -= src_step )
3177 T t0 = dct_wave->re*src[0] - dct_wave->im*src1[0];
3178 T t1 = -dct_wave->im*src[0] - dct_wave->re*src1[0];
3179 dft_src[j*2-1] = t0;
3183 dft_src[n-1] = (T)(src[0]*2*dct_wave->re);
3184 CCSIDFT( dft_src, dft_dst, n, nf, factors, itab,
3185 dft_wave, n, spec, buf, 0, 1.0 );
3187 for( j = 0; j < n2; j++, dst += dst_step*2 )
3189 dst[0] = dft_dst[j];
3190 dst[dst_step] = dft_dst[n-j-1];
3196 DCTInit( int n, int elem_size, void* _wave, int inv )
3198 static const double DctScale[] =
3200 0.707106781186547570, 0.500000000000000000, 0.353553390593273790,
3201 0.250000000000000000, 0.176776695296636890, 0.125000000000000000,
3202 0.088388347648318447, 0.062500000000000000, 0.044194173824159223,
3203 0.031250000000000000, 0.022097086912079612, 0.015625000000000000,
3204 0.011048543456039806, 0.007812500000000000, 0.005524271728019903,
3205 0.003906250000000000, 0.002762135864009952, 0.001953125000000000,
3206 0.001381067932004976, 0.000976562500000000, 0.000690533966002488,
3207 0.000488281250000000, 0.000345266983001244, 0.000244140625000000,
3208 0.000172633491500622, 0.000122070312500000, 0.000086316745750311,
3209 0.000061035156250000, 0.000043158372875155, 0.000030517578125000
3213 Complex<double> w, w1;
3219 assert( (n&1) == 0 );
3221 if( (n & (n - 1)) == 0 )
3224 for( m = 0; (unsigned)(1 << m) < (unsigned)n; m++ )
3226 scale = (!inv ? 2 : 1)*DctScale[m];
3227 w1.re = DFTTab[m+2][0];
3228 w1.im = -DFTTab[m+2][1];
3233 scale = (!inv ? 2 : 1)*std::sqrt(t);
3234 w1.im = sin(-CV_PI*t);
3235 w1.re = std::sqrt(1. - w1.im*w1.im);
3239 if( elem_size == sizeof(Complex<double>) )
3241 Complex<double>* wave = (Complex<double>*)_wave;
3246 for( i = 0; i <= n; i++ )
3249 t = w.re*w1.re - w.im*w1.im;
3250 w.im = w.re*w1.im + w.im*w1.re;
3256 Complex<float>* wave = (Complex<float>*)_wave;
3257 assert( elem_size == sizeof(Complex<float>) );
3259 w.re = (float)scale;
3262 for( i = 0; i <= n; i++ )
3264 wave[i].re = (float)w.re;
3265 wave[i].im = (float)w.im;
3266 t = w.re*w1.re - w.im*w1.im;
3267 w.im = w.re*w1.im + w.im*w1.re;
3274 typedef void (*DCTFunc)(const void* src, int src_step, void* dft_src,
3275 void* dft_dst, void* dst, int dst_step, int n,
3276 int nf, int* factors, const int* itab, const void* dft_wave,
3277 const void* dct_wave, const void* spec, void* buf );
3279 static void DCT_32f(const float* src, int src_step, float* dft_src, float* dft_dst,
3280 float* dst, int dst_step, int n, int nf, int* factors, const int* itab,
3281 const Complexf* dft_wave, const Complexf* dct_wave, const void* spec, Complexf* buf )
3283 DCT(src, src_step, dft_src, dft_dst, dst, dst_step,
3284 n, nf, factors, itab, dft_wave, dct_wave, spec, buf);
3287 static void IDCT_32f(const float* src, int src_step, float* dft_src, float* dft_dst,
3288 float* dst, int dst_step, int n, int nf, int* factors, const int* itab,
3289 const Complexf* dft_wave, const Complexf* dct_wave, const void* spec, Complexf* buf )
3291 IDCT(src, src_step, dft_src, dft_dst, dst, dst_step,
3292 n, nf, factors, itab, dft_wave, dct_wave, spec, buf);
3295 static void DCT_64f(const double* src, int src_step, double* dft_src, double* dft_dst,
3296 double* dst, int dst_step, int n, int nf, int* factors, const int* itab,
3297 const Complexd* dft_wave, const Complexd* dct_wave, const void* spec, Complexd* buf )
3299 DCT(src, src_step, dft_src, dft_dst, dst, dst_step,
3300 n, nf, factors, itab, dft_wave, dct_wave, spec, buf);
3303 static void IDCT_64f(const double* src, int src_step, double* dft_src, double* dft_dst,
3304 double* dst, int dst_step, int n, int nf, int* factors, const int* itab,
3305 const Complexd* dft_wave, const Complexd* dct_wave, const void* spec, Complexd* buf )
3307 IDCT(src, src_step, dft_src, dft_dst, dst, dst_step,
3308 n, nf, factors, itab, dft_wave, dct_wave, spec, buf);
3315 #if defined HAVE_IPP && IPP_VERSION_MAJOR >= 7
3317 typedef IppStatus (CV_STDCALL * ippiDCTFunc)(const Ipp32f*, int, Ipp32f*, int, const void*, Ipp8u*);
3318 typedef IppStatus (CV_STDCALL * ippiDCTInitAlloc)(void**, IppiSize, IppHintAlgorithm);
3319 typedef IppStatus (CV_STDCALL * ippiDCTFree)(void* pDCTSpec);
3320 typedef IppStatus (CV_STDCALL * ippiDCTGetBufSize)(const void*, int*);
3322 template <typename Dct>
3323 class DctIPPLoop_Invoker : public ParallelLoopBody
3327 DctIPPLoop_Invoker(const Mat& _src, Mat& _dst, const Dct* _ippidct, bool _inv, bool *_ok) :
3328 ParallelLoopBody(), src(&_src), dst(&_dst), ippidct(_ippidct), inv(_inv), ok(_ok)
3333 virtual void operator()(const Range& range) const
3336 AutoBuffer<uchar> buf;
3340 IppiSize srcRoiSize = {src->cols, 1};
3342 CV_SUPPRESS_DEPRECATED_START
3344 ippiDCTInitAlloc ippInitAlloc = inv ? (ippiDCTInitAlloc)ippiDCTInvInitAlloc_32f : (ippiDCTInitAlloc)ippiDCTFwdInitAlloc_32f;
3345 ippiDCTFree ippFree = inv ? (ippiDCTFree)ippiDCTInvFree_32f : (ippiDCTFree)ippiDCTFwdFree_32f;
3346 ippiDCTGetBufSize ippGetBufSize = inv ? (ippiDCTGetBufSize)ippiDCTInvGetBufSize_32f : (ippiDCTGetBufSize)ippiDCTFwdGetBufSize_32f;
3348 if (ippInitAlloc(&pDCTSpec, srcRoiSize, ippAlgHintNone)>=0 && ippGetBufSize(pDCTSpec, &bufSize)>=0)
3350 buf.allocate( bufSize );
3351 pBuffer = (uchar*)buf;
3353 for( int i = range.start; i < range.end; ++i)
3354 if(!(*ippidct)(src->ptr<float>(i), (int)src->step,dst->ptr<float>(i), (int)dst->step, pDCTSpec, (Ipp8u*)pBuffer))
3363 CV_SUPPRESS_DEPRECATED_END
3374 template <typename Dct>
3375 bool DctIPPLoop(const Mat& src, Mat& dst, const Dct& ippidct, bool inv)
3378 parallel_for_(Range(0, src.rows), DctIPPLoop_Invoker<Dct>(src, dst, &ippidct, inv, &ok), src.rows/(double)(1<<4) );
3382 struct IPPDCTFunctor
3384 IPPDCTFunctor(ippiDCTFunc _func) : func(_func){}
3386 bool operator()(const Ipp32f* src, int srcStep, Ipp32f* dst, int dstStep, const void* pDCTSpec, Ipp8u* pBuffer) const
3388 return func ? func(src, srcStep, dst, dstStep, pDCTSpec, pBuffer) >= 0 : false;
3394 static bool ippi_DCT_32f(const Mat& src, Mat& dst, bool inv, bool row)
3396 ippiDCTFunc ippFunc = inv ? (ippiDCTFunc)ippiDCTInv_32f_C1R : (ippiDCTFunc)ippiDCTFwd_32f_C1R ;
3399 return(DctIPPLoop(src,dst,IPPDCTFunctor(ippFunc),inv));
3404 AutoBuffer<uchar> buf;
3408 IppiSize srcRoiSize = {src.cols, src.rows};
3410 CV_SUPPRESS_DEPRECATED_START
3412 ippiDCTInitAlloc ippInitAlloc = inv ? (ippiDCTInitAlloc)ippiDCTInvInitAlloc_32f : (ippiDCTInitAlloc)ippiDCTFwdInitAlloc_32f;
3413 ippiDCTFree ippFree = inv ? (ippiDCTFree)ippiDCTInvFree_32f : (ippiDCTFree)ippiDCTFwdFree_32f;
3414 ippiDCTGetBufSize ippGetBufSize = inv ? (ippiDCTGetBufSize)ippiDCTInvGetBufSize_32f : (ippiDCTGetBufSize)ippiDCTFwdGetBufSize_32f;
3418 if (ippInitAlloc(&pDCTSpec, srcRoiSize, ippAlgHintNone)>=0 && ippGetBufSize(pDCTSpec, &bufSize)>=0)
3420 buf.allocate( bufSize );
3421 pBuffer = (uchar*)buf;
3423 status = ippFunc(src.ptr<float>(), (int)src.step, dst.ptr<float>(), (int)dst.step, pDCTSpec, (Ipp8u*)pBuffer);
3429 CV_SUPPRESS_DEPRECATED_END
3438 void cv::dct( InputArray _src0, OutputArray _dst, int flags )
3440 static DCTFunc dct_tbl[4] =
3448 bool inv = (flags & DCT_INVERSE) != 0;
3449 Mat src0 = _src0.getMat(), src = src0;
3450 int type = src.type(), depth = src.depth();
3454 int prev_len = 0, nf = 0, stage, end_stage;
3455 uchar *src_dft_buf = 0, *dst_dft_buf = 0;
3456 uchar *dft_wave = 0, *dct_wave = 0;
3459 int elem_size = (int)src.elemSize(), complex_elem_size = elem_size*2;
3460 int factors[34], inplace_transform;
3462 AutoBuffer<uchar> buf;
3464 CV_Assert( type == CV_32FC1 || type == CV_64FC1 );
3465 _dst.create( src.rows, src.cols, type );
3466 Mat dst = _dst.getMat();
3468 #if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7)
3471 bool row = (flags & DCT_ROWS) != 0;
3472 if (src.type() == CV_32F)
3474 if(ippi_DCT_32f(src,dst,inv, row))
3476 CV_IMPL_ADD(CV_IMPL_IPP);
3479 setIppErrorStatus();
3484 DCTFunc dct_func = dct_tbl[(int)inv + (depth == CV_64F)*2];
3486 if( (flags & DCT_ROWS) || src.rows == 1 ||
3487 (src.cols == 1 && (src.isContinuous() && dst.isContinuous())))
3489 stage = end_stage = 0;
3493 stage = src.cols == 1;
3497 for( ; stage <= end_stage; stage++ )
3499 const uchar* sptr = src.ptr();
3500 uchar* dptr = dst.ptr();
3501 size_t sstep0, sstep1, dstep0, dstep1;
3507 if( len == 1 && !(flags & DCT_ROWS) )
3514 sstep1 = dstep1 = elem_size;
3522 sstep0 = dstep0 = elem_size;
3525 if( len != prev_len )
3529 if( len > 1 && (len & 1) )
3530 CV_Error( CV_StsNotImplemented, "Odd-size DCT\'s are not implemented" );
3533 sz += (len/2 + 1)*complex_elem_size;
3536 inplace_transform = 1;
3538 sz += len*(complex_elem_size + sizeof(int)) + complex_elem_size;
3540 nf = DFTFactorize( len, factors );
3541 inplace_transform = factors[0] == factors[nf-1];
3543 i = nf > 1 && (factors[0] & 1) == 0;
3544 if( (factors[i] & 1) != 0 && factors[i] > 5 )
3545 sz += (factors[i]+1)*complex_elem_size;
3547 if( !inplace_transform )
3548 sz += len*elem_size;
3551 buf.allocate( sz + 32 );
3557 ptr += len*complex_elem_size;
3559 ptr = (uchar*)cvAlignPtr( ptr + len*sizeof(int), 16 );
3560 DFTInit( len, nf, factors, itab, complex_elem_size, dft_wave, inv );
3564 ptr += (len/2 + 1)*complex_elem_size;
3565 src_dft_buf = dst_dft_buf = ptr;
3566 ptr += len*elem_size;
3567 if( !inplace_transform )
3570 ptr += len*elem_size;
3572 DCTInit( len, complex_elem_size, dct_wave, inv );
3577 // otherwise reuse the tables calculated on the previous stage
3578 for( i = 0; i < count; i++ )
3580 dct_func( sptr + i*sstep0, (int)sstep1, src_dft_buf, dst_dft_buf,
3581 dptr + i*dstep0, (int)dstep1, len, nf, factors,
3582 itab, dft_wave, dct_wave, spec, ptr );
3589 void cv::idct( InputArray src, OutputArray dst, int flags )
3591 dct( src, dst, flags | DCT_INVERSE );
3597 static const int optimalDFTSizeTab[] = {
3598 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24, 25, 27, 30, 32, 36, 40, 45, 48,
3599 50, 54, 60, 64, 72, 75, 80, 81, 90, 96, 100, 108, 120, 125, 128, 135, 144, 150, 160,
3600 162, 180, 192, 200, 216, 225, 240, 243, 250, 256, 270, 288, 300, 320, 324, 360, 375,
3601 384, 400, 405, 432, 450, 480, 486, 500, 512, 540, 576, 600, 625, 640, 648, 675, 720,
3602 729, 750, 768, 800, 810, 864, 900, 960, 972, 1000, 1024, 1080, 1125, 1152, 1200,
3603 1215, 1250, 1280, 1296, 1350, 1440, 1458, 1500, 1536, 1600, 1620, 1728, 1800, 1875,
3604 1920, 1944, 2000, 2025, 2048, 2160, 2187, 2250, 2304, 2400, 2430, 2500, 2560, 2592,
3605 2700, 2880, 2916, 3000, 3072, 3125, 3200, 3240, 3375, 3456, 3600, 3645, 3750, 3840,
3606 3888, 4000, 4050, 4096, 4320, 4374, 4500, 4608, 4800, 4860, 5000, 5120, 5184, 5400,
3607 5625, 5760, 5832, 6000, 6075, 6144, 6250, 6400, 6480, 6561, 6750, 6912, 7200, 7290,
3608 7500, 7680, 7776, 8000, 8100, 8192, 8640, 8748, 9000, 9216, 9375, 9600, 9720, 10000,
3609 10125, 10240, 10368, 10800, 10935, 11250, 11520, 11664, 12000, 12150, 12288, 12500,
3610 12800, 12960, 13122, 13500, 13824, 14400, 14580, 15000, 15360, 15552, 15625, 16000,
3611 16200, 16384, 16875, 17280, 17496, 18000, 18225, 18432, 18750, 19200, 19440, 19683,
3612 20000, 20250, 20480, 20736, 21600, 21870, 22500, 23040, 23328, 24000, 24300, 24576,
3613 25000, 25600, 25920, 26244, 27000, 27648, 28125, 28800, 29160, 30000, 30375, 30720,
3614 31104, 31250, 32000, 32400, 32768, 32805, 33750, 34560, 34992, 36000, 36450, 36864,
3615 37500, 38400, 38880, 39366, 40000, 40500, 40960, 41472, 43200, 43740, 45000, 46080,
3616 46656, 46875, 48000, 48600, 49152, 50000, 50625, 51200, 51840, 52488, 54000, 54675,
3617 55296, 56250, 57600, 58320, 59049, 60000, 60750, 61440, 62208, 62500, 64000, 64800,
3618 65536, 65610, 67500, 69120, 69984, 72000, 72900, 73728, 75000, 76800, 77760, 78125,
3619 78732, 80000, 81000, 81920, 82944, 84375, 86400, 87480, 90000, 91125, 92160, 93312,
3620 93750, 96000, 97200, 98304, 98415, 100000, 101250, 102400, 103680, 104976, 108000,
3621 109350, 110592, 112500, 115200, 116640, 118098, 120000, 121500, 122880, 124416, 125000,
3622 128000, 129600, 131072, 131220, 135000, 138240, 139968, 140625, 144000, 145800, 147456,
3623 150000, 151875, 153600, 155520, 156250, 157464, 160000, 162000, 163840, 164025, 165888,
3624 168750, 172800, 174960, 177147, 180000, 182250, 184320, 186624, 187500, 192000, 194400,
3625 196608, 196830, 200000, 202500, 204800, 207360, 209952, 216000, 218700, 221184, 225000,
3626 230400, 233280, 234375, 236196, 240000, 243000, 245760, 248832, 250000, 253125, 256000,
3627 259200, 262144, 262440, 270000, 273375, 276480, 279936, 281250, 288000, 291600, 294912,
3628 295245, 300000, 303750, 307200, 311040, 312500, 314928, 320000, 324000, 327680, 328050,
3629 331776, 337500, 345600, 349920, 354294, 360000, 364500, 368640, 373248, 375000, 384000,
3630 388800, 390625, 393216, 393660, 400000, 405000, 409600, 414720, 419904, 421875, 432000,
3631 437400, 442368, 450000, 455625, 460800, 466560, 468750, 472392, 480000, 486000, 491520,
3632 492075, 497664, 500000, 506250, 512000, 518400, 524288, 524880, 531441, 540000, 546750,
3633 552960, 559872, 562500, 576000, 583200, 589824, 590490, 600000, 607500, 614400, 622080,
3634 625000, 629856, 640000, 648000, 655360, 656100, 663552, 675000, 691200, 699840, 703125,
3635 708588, 720000, 729000, 737280, 746496, 750000, 759375, 768000, 777600, 781250, 786432,
3636 787320, 800000, 810000, 819200, 820125, 829440, 839808, 843750, 864000, 874800, 884736,
3637 885735, 900000, 911250, 921600, 933120, 937500, 944784, 960000, 972000, 983040, 984150,
3638 995328, 1000000, 1012500, 1024000, 1036800, 1048576, 1049760, 1062882, 1080000, 1093500,
3639 1105920, 1119744, 1125000, 1152000, 1166400, 1171875, 1179648, 1180980, 1200000,
3640 1215000, 1228800, 1244160, 1250000, 1259712, 1265625, 1280000, 1296000, 1310720,
3641 1312200, 1327104, 1350000, 1366875, 1382400, 1399680, 1406250, 1417176, 1440000,
3642 1458000, 1474560, 1476225, 1492992, 1500000, 1518750, 1536000, 1555200, 1562500,
3643 1572864, 1574640, 1594323, 1600000, 1620000, 1638400, 1640250, 1658880, 1679616,
3644 1687500, 1728000, 1749600, 1769472, 1771470, 1800000, 1822500, 1843200, 1866240,
3645 1875000, 1889568, 1920000, 1944000, 1953125, 1966080, 1968300, 1990656, 2000000,
3646 2025000, 2048000, 2073600, 2097152, 2099520, 2109375, 2125764, 2160000, 2187000,
3647 2211840, 2239488, 2250000, 2278125, 2304000, 2332800, 2343750, 2359296, 2361960,
3648 2400000, 2430000, 2457600, 2460375, 2488320, 2500000, 2519424, 2531250, 2560000,
3649 2592000, 2621440, 2624400, 2654208, 2657205, 2700000, 2733750, 2764800, 2799360,
3650 2812500, 2834352, 2880000, 2916000, 2949120, 2952450, 2985984, 3000000, 3037500,
3651 3072000, 3110400, 3125000, 3145728, 3149280, 3188646, 3200000, 3240000, 3276800,
3652 3280500, 3317760, 3359232, 3375000, 3456000, 3499200, 3515625, 3538944, 3542940,
3653 3600000, 3645000, 3686400, 3732480, 3750000, 3779136, 3796875, 3840000, 3888000,
3654 3906250, 3932160, 3936600, 3981312, 4000000, 4050000, 4096000, 4100625, 4147200,
3655 4194304, 4199040, 4218750, 4251528, 4320000, 4374000, 4423680, 4428675, 4478976,
3656 4500000, 4556250, 4608000, 4665600, 4687500, 4718592, 4723920, 4782969, 4800000,
3657 4860000, 4915200, 4920750, 4976640, 5000000, 5038848, 5062500, 5120000, 5184000,
3658 5242880, 5248800, 5308416, 5314410, 5400000, 5467500, 5529600, 5598720, 5625000,
3659 5668704, 5760000, 5832000, 5859375, 5898240, 5904900, 5971968, 6000000, 6075000,
3660 6144000, 6220800, 6250000, 6291456, 6298560, 6328125, 6377292, 6400000, 6480000,
3661 6553600, 6561000, 6635520, 6718464, 6750000, 6834375, 6912000, 6998400, 7031250,
3662 7077888, 7085880, 7200000, 7290000, 7372800, 7381125, 7464960, 7500000, 7558272,
3663 7593750, 7680000, 7776000, 7812500, 7864320, 7873200, 7962624, 7971615, 8000000,
3664 8100000, 8192000, 8201250, 8294400, 8388608, 8398080, 8437500, 8503056, 8640000,
3665 8748000, 8847360, 8857350, 8957952, 9000000, 9112500, 9216000, 9331200, 9375000,
3666 9437184, 9447840, 9565938, 9600000, 9720000, 9765625, 9830400, 9841500, 9953280,
3667 10000000, 10077696, 10125000, 10240000, 10368000, 10485760, 10497600, 10546875, 10616832,
3668 10628820, 10800000, 10935000, 11059200, 11197440, 11250000, 11337408, 11390625, 11520000,
3669 11664000, 11718750, 11796480, 11809800, 11943936, 12000000, 12150000, 12288000, 12301875,
3670 12441600, 12500000, 12582912, 12597120, 12656250, 12754584, 12800000, 12960000, 13107200,
3671 13122000, 13271040, 13286025, 13436928, 13500000, 13668750, 13824000, 13996800, 14062500,
3672 14155776, 14171760, 14400000, 14580000, 14745600, 14762250, 14929920, 15000000, 15116544,
3673 15187500, 15360000, 15552000, 15625000, 15728640, 15746400, 15925248, 15943230, 16000000,
3674 16200000, 16384000, 16402500, 16588800, 16777216, 16796160, 16875000, 17006112, 17280000,
3675 17496000, 17578125, 17694720, 17714700, 17915904, 18000000, 18225000, 18432000, 18662400,
3676 18750000, 18874368, 18895680, 18984375, 19131876, 19200000, 19440000, 19531250, 19660800,
3677 19683000, 19906560, 20000000, 20155392, 20250000, 20480000, 20503125, 20736000, 20971520,
3678 20995200, 21093750, 21233664, 21257640, 21600000, 21870000, 22118400, 22143375, 22394880,
3679 22500000, 22674816, 22781250, 23040000, 23328000, 23437500, 23592960, 23619600, 23887872,
3680 23914845, 24000000, 24300000, 24576000, 24603750, 24883200, 25000000, 25165824, 25194240,
3681 25312500, 25509168, 25600000, 25920000, 26214400, 26244000, 26542080, 26572050, 26873856,
3682 27000000, 27337500, 27648000, 27993600, 28125000, 28311552, 28343520, 28800000, 29160000,
3683 29296875, 29491200, 29524500, 29859840, 30000000, 30233088, 30375000, 30720000, 31104000,
3684 31250000, 31457280, 31492800, 31640625, 31850496, 31886460, 32000000, 32400000, 32768000,
3685 32805000, 33177600, 33554432, 33592320, 33750000, 34012224, 34171875, 34560000, 34992000,
3686 35156250, 35389440, 35429400, 35831808, 36000000, 36450000, 36864000, 36905625, 37324800,
3687 37500000, 37748736, 37791360, 37968750, 38263752, 38400000, 38880000, 39062500, 39321600,
3688 39366000, 39813120, 39858075, 40000000, 40310784, 40500000, 40960000, 41006250, 41472000,
3689 41943040, 41990400, 42187500, 42467328, 42515280, 43200000, 43740000, 44236800, 44286750,
3690 44789760, 45000000, 45349632, 45562500, 46080000, 46656000, 46875000, 47185920, 47239200,
3691 47775744, 47829690, 48000000, 48600000, 48828125, 49152000, 49207500, 49766400, 50000000,
3692 50331648, 50388480, 50625000, 51018336, 51200000, 51840000, 52428800, 52488000, 52734375,
3693 53084160, 53144100, 53747712, 54000000, 54675000, 55296000, 55987200, 56250000, 56623104,
3694 56687040, 56953125, 57600000, 58320000, 58593750, 58982400, 59049000, 59719680, 60000000,
3695 60466176, 60750000, 61440000, 61509375, 62208000, 62500000, 62914560, 62985600, 63281250,
3696 63700992, 63772920, 64000000, 64800000, 65536000, 65610000, 66355200, 66430125, 67108864,
3697 67184640, 67500000, 68024448, 68343750, 69120000, 69984000, 70312500, 70778880, 70858800,
3698 71663616, 72000000, 72900000, 73728000, 73811250, 74649600, 75000000, 75497472, 75582720,
3699 75937500, 76527504, 76800000, 77760000, 78125000, 78643200, 78732000, 79626240, 79716150,
3700 80000000, 80621568, 81000000, 81920000, 82012500, 82944000, 83886080, 83980800, 84375000,
3701 84934656, 85030560, 86400000, 87480000, 87890625, 88473600, 88573500, 89579520, 90000000,
3702 90699264, 91125000, 92160000, 93312000, 93750000, 94371840, 94478400, 94921875, 95551488,
3703 95659380, 96000000, 97200000, 97656250, 98304000, 98415000, 99532800, 100000000,
3704 100663296, 100776960, 101250000, 102036672, 102400000, 102515625, 103680000, 104857600,
3705 104976000, 105468750, 106168320, 106288200, 107495424, 108000000, 109350000, 110592000,
3706 110716875, 111974400, 112500000, 113246208, 113374080, 113906250, 115200000, 116640000,
3707 117187500, 117964800, 118098000, 119439360, 119574225, 120000000, 120932352, 121500000,
3708 122880000, 123018750, 124416000, 125000000, 125829120, 125971200, 126562500, 127401984,
3709 127545840, 128000000, 129600000, 131072000, 131220000, 132710400, 132860250, 134217728,
3710 134369280, 135000000, 136048896, 136687500, 138240000, 139968000, 140625000, 141557760,
3711 141717600, 143327232, 144000000, 145800000, 146484375, 147456000, 147622500, 149299200,
3712 150000000, 150994944, 151165440, 151875000, 153055008, 153600000, 155520000, 156250000,
3713 157286400, 157464000, 158203125, 159252480, 159432300, 160000000, 161243136, 162000000,
3714 163840000, 164025000, 165888000, 167772160, 167961600, 168750000, 169869312, 170061120,
3715 170859375, 172800000, 174960000, 175781250, 176947200, 177147000, 179159040, 180000000,
3716 181398528, 182250000, 184320000, 184528125, 186624000, 187500000, 188743680, 188956800,
3717 189843750, 191102976, 191318760, 192000000, 194400000, 195312500, 196608000, 196830000,
3718 199065600, 199290375, 200000000, 201326592, 201553920, 202500000, 204073344, 204800000,
3719 205031250, 207360000, 209715200, 209952000, 210937500, 212336640, 212576400, 214990848,
3720 216000000, 218700000, 221184000, 221433750, 223948800, 225000000, 226492416, 226748160,
3721 227812500, 230400000, 233280000, 234375000, 235929600, 236196000, 238878720, 239148450,
3722 240000000, 241864704, 243000000, 244140625, 245760000, 246037500, 248832000, 250000000,
3723 251658240, 251942400, 253125000, 254803968, 255091680, 256000000, 259200000, 262144000,
3724 262440000, 263671875, 265420800, 265720500, 268435456, 268738560, 270000000, 272097792,
3725 273375000, 276480000, 279936000, 281250000, 283115520, 283435200, 284765625, 286654464,
3726 288000000, 291600000, 292968750, 294912000, 295245000, 298598400, 300000000, 301989888,
3727 302330880, 303750000, 306110016, 307200000, 307546875, 311040000, 312500000, 314572800,
3728 314928000, 316406250, 318504960, 318864600, 320000000, 322486272, 324000000, 327680000,
3729 328050000, 331776000, 332150625, 335544320, 335923200, 337500000, 339738624, 340122240,
3730 341718750, 345600000, 349920000, 351562500, 353894400, 354294000, 358318080, 360000000,
3731 362797056, 364500000, 368640000, 369056250, 373248000, 375000000, 377487360, 377913600,
3732 379687500, 382205952, 382637520, 384000000, 388800000, 390625000, 393216000, 393660000,
3733 398131200, 398580750, 400000000, 402653184, 403107840, 405000000, 408146688, 409600000,
3734 410062500, 414720000, 419430400, 419904000, 421875000, 424673280, 425152800, 429981696,
3735 432000000, 437400000, 439453125, 442368000, 442867500, 447897600, 450000000, 452984832,
3736 453496320, 455625000, 460800000, 466560000, 468750000, 471859200, 472392000, 474609375,
3737 477757440, 478296900, 480000000, 483729408, 486000000, 488281250, 491520000, 492075000,
3738 497664000, 500000000, 503316480, 503884800, 506250000, 509607936, 510183360, 512000000,
3739 512578125, 518400000, 524288000, 524880000, 527343750, 530841600, 531441000, 536870912,
3740 537477120, 540000000, 544195584, 546750000, 552960000, 553584375, 559872000, 562500000,
3741 566231040, 566870400, 569531250, 573308928, 576000000, 583200000, 585937500, 589824000,
3742 590490000, 597196800, 597871125, 600000000, 603979776, 604661760, 607500000, 612220032,
3743 614400000, 615093750, 622080000, 625000000, 629145600, 629856000, 632812500, 637009920,
3744 637729200, 640000000, 644972544, 648000000, 655360000, 656100000, 663552000, 664301250,
3745 671088640, 671846400, 675000000, 679477248, 680244480, 683437500, 691200000, 699840000,
3746 703125000, 707788800, 708588000, 716636160, 720000000, 725594112, 729000000, 732421875,
3747 737280000, 738112500, 746496000, 750000000, 754974720, 755827200, 759375000, 764411904,
3748 765275040, 768000000, 777600000, 781250000, 786432000, 787320000, 791015625, 796262400,
3749 797161500, 800000000, 805306368, 806215680, 810000000, 816293376, 819200000, 820125000,
3750 829440000, 838860800, 839808000, 843750000, 849346560, 850305600, 854296875, 859963392,
3751 864000000, 874800000, 878906250, 884736000, 885735000, 895795200, 900000000, 905969664,
3752 906992640, 911250000, 921600000, 922640625, 933120000, 937500000, 943718400, 944784000,
3753 949218750, 955514880, 956593800, 960000000, 967458816, 972000000, 976562500, 983040000,
3754 984150000, 995328000, 996451875, 1000000000, 1006632960, 1007769600, 1012500000,
3755 1019215872, 1020366720, 1024000000, 1025156250, 1036800000, 1048576000, 1049760000,
3756 1054687500, 1061683200, 1062882000, 1073741824, 1074954240, 1080000000, 1088391168,
3757 1093500000, 1105920000, 1107168750, 1119744000, 1125000000, 1132462080, 1133740800,
3758 1139062500, 1146617856, 1152000000, 1166400000, 1171875000, 1179648000, 1180980000,
3759 1194393600, 1195742250, 1200000000, 1207959552, 1209323520, 1215000000, 1220703125,
3760 1224440064, 1228800000, 1230187500, 1244160000, 1250000000, 1258291200, 1259712000,
3761 1265625000, 1274019840, 1275458400, 1280000000, 1289945088, 1296000000, 1310720000,
3762 1312200000, 1318359375, 1327104000, 1328602500, 1342177280, 1343692800, 1350000000,
3763 1358954496, 1360488960, 1366875000, 1382400000, 1399680000, 1406250000, 1415577600,
3764 1417176000, 1423828125, 1433272320, 1440000000, 1451188224, 1458000000, 1464843750,
3765 1474560000, 1476225000, 1492992000, 1500000000, 1509949440, 1511654400, 1518750000,
3766 1528823808, 1530550080, 1536000000, 1537734375, 1555200000, 1562500000, 1572864000,
3767 1574640000, 1582031250, 1592524800, 1594323000, 1600000000, 1610612736, 1612431360,
3768 1620000000, 1632586752, 1638400000, 1640250000, 1658880000, 1660753125, 1677721600,
3769 1679616000, 1687500000, 1698693120, 1700611200, 1708593750, 1719926784, 1728000000,
3770 1749600000, 1757812500, 1769472000, 1771470000, 1791590400, 1800000000, 1811939328,
3771 1813985280, 1822500000, 1843200000, 1845281250, 1866240000, 1875000000, 1887436800,
3772 1889568000, 1898437500, 1911029760, 1913187600, 1920000000, 1934917632, 1944000000,
3773 1953125000, 1966080000, 1968300000, 1990656000, 1992903750, 2000000000, 2013265920,
3774 2015539200, 2025000000, 2038431744, 2040733440, 2048000000, 2050312500, 2073600000,
3775 2097152000, 2099520000, 2109375000, 2123366400, 2125764000
3780 int cv::getOptimalDFTSize( int size0 )
3782 int a = 0, b = sizeof(optimalDFTSizeTab)/sizeof(optimalDFTSizeTab[0]) - 1;
3783 if( (unsigned)size0 >= (unsigned)optimalDFTSizeTab[b] )
3788 int c = (a + b) >> 1;
3789 if( size0 <= optimalDFTSizeTab[c] )
3795 return optimalDFTSizeTab[b];
3799 cvDFT( const CvArr* srcarr, CvArr* dstarr, int flags, int nonzero_rows )
3801 cv::Mat src = cv::cvarrToMat(srcarr), dst0 = cv::cvarrToMat(dstarr), dst = dst0;
3802 int _flags = ((flags & CV_DXT_INVERSE) ? cv::DFT_INVERSE : 0) |
3803 ((flags & CV_DXT_SCALE) ? cv::DFT_SCALE : 0) |
3804 ((flags & CV_DXT_ROWS) ? cv::DFT_ROWS : 0);
3806 CV_Assert( src.size == dst.size );
3808 if( src.type() != dst.type() )
3810 if( dst.channels() == 2 )
3811 _flags |= cv::DFT_COMPLEX_OUTPUT;
3813 _flags |= cv::DFT_REAL_OUTPUT;
3816 cv::dft( src, dst, _flags, nonzero_rows );
3817 CV_Assert( dst.data == dst0.data ); // otherwise it means that the destination size or type was incorrect
3822 cvMulSpectrums( const CvArr* srcAarr, const CvArr* srcBarr,
3823 CvArr* dstarr, int flags )
3825 cv::Mat srcA = cv::cvarrToMat(srcAarr),
3826 srcB = cv::cvarrToMat(srcBarr),
3827 dst = cv::cvarrToMat(dstarr);
3828 CV_Assert( srcA.size == dst.size && srcA.type() == dst.type() );
3830 cv::mulSpectrums(srcA, srcB, dst,
3831 (flags & CV_DXT_ROWS) ? cv::DFT_ROWS : 0,
3832 (flags & CV_DXT_MUL_CONJ) != 0 );
3837 cvDCT( const CvArr* srcarr, CvArr* dstarr, int flags )
3839 cv::Mat src = cv::cvarrToMat(srcarr), dst = cv::cvarrToMat(dstarr);
3840 CV_Assert( src.size == dst.size && src.type() == dst.type() );
3841 int _flags = ((flags & CV_DXT_INVERSE) ? cv::DCT_INVERSE : 0) |
3842 ((flags & CV_DXT_ROWS) ? cv::DCT_ROWS : 0);
3843 cv::dct( src, dst, _flags );
3848 cvGetOptimalDFTSize( int size0 )
3850 return cv::getOptimalDFTSize(size0);