16acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*M///////////////////////////////////////////////////////////////////////////////////////
26acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
36acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
46acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
56acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  By downloading, copying, installing or using the software you agree to this license.
66acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  If you do not agree to this license, do not download, install,
76acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  copy or use the software.
86acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
96acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                        Intel License Agreement
116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                For Open Source Computer Vision Library
126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Copyright (C) 2000, Intel Corporation, all rights reserved.
146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Third party copyrights are property of their respective owners.
156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Redistribution and use in source and binary forms, with or without modification,
176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// are permitted provided that the following conditions are met:
186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//   * Redistribution's of source code must retain the above copyright notice,
206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     this list of conditions and the following disclaimer.
216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//   * Redistribution's in binary form must reproduce the above copyright notice,
236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     this list of conditions and the following disclaimer in the documentation
246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     and/or other materials provided with the distribution.
256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//   * The name of Intel Corporation may not be used to endorse or promote products
276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     derived from this software without specific prior written permission.
286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// This software is provided by the copyright holders and contributors "as is" and
306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// any express or implied warranties, including, but not limited to, the implied
316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// warranties of merchantability and fitness for a particular purpose are disclaimed.
326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// In no event shall the Intel Corporation or contributors be liable for any direct,
336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// indirect, incidental, special, exemplary, or consequential damages
346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// (including, but not limited to, procurement of substitute goods or services;
356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// loss of use, data, or profits; or business interruption) however caused
366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// and on any theory of liability, whether in contract, strict liability,
376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// or tort (including negligence or otherwise) arising in any way out of
386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// the use of this software, even if advised of the possibility of such damage.
396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//M*/
416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "_cxcore.h"
436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// On Win64 (IA64) optimized versions of DFT and DCT fail the tests
456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#if defined WIN64 && !defined EM64T
466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#pragma optimize("", off)
476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#endif
486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvDFTInitAlloc_C_32fc_t icvDFTInitAlloc_C_32fc_p = 0;
506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvDFTFree_C_32fc_t icvDFTFree_C_32fc_p = 0;
516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvDFTGetBufSize_C_32fc_t icvDFTGetBufSize_C_32fc_p = 0;
526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvDFTFwd_CToC_32fc_t icvDFTFwd_CToC_32fc_p = 0;
536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvDFTInv_CToC_32fc_t icvDFTInv_CToC_32fc_p = 0;
546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvDFTInitAlloc_C_64fc_t icvDFTInitAlloc_C_64fc_p = 0;
566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvDFTFree_C_64fc_t icvDFTFree_C_64fc_p = 0;
576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvDFTGetBufSize_C_64fc_t icvDFTGetBufSize_C_64fc_p = 0;
586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvDFTFwd_CToC_64fc_t icvDFTFwd_CToC_64fc_p = 0;
596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvDFTInv_CToC_64fc_t icvDFTInv_CToC_64fc_p = 0;
606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvDFTInitAlloc_R_32f_t icvDFTInitAlloc_R_32f_p = 0;
626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvDFTFree_R_32f_t icvDFTFree_R_32f_p = 0;
636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvDFTGetBufSize_R_32f_t icvDFTGetBufSize_R_32f_p = 0;
646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvDFTFwd_RToPack_32f_t icvDFTFwd_RToPack_32f_p = 0;
656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvDFTInv_PackToR_32f_t icvDFTInv_PackToR_32f_p = 0;
666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvDFTInitAlloc_R_64f_t icvDFTInitAlloc_R_64f_p = 0;
686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvDFTFree_R_64f_t icvDFTFree_R_64f_p = 0;
696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvDFTGetBufSize_R_64f_t icvDFTGetBufSize_R_64f_p = 0;
706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvDFTFwd_RToPack_64f_t icvDFTFwd_RToPack_64f_p = 0;
716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvDFTInv_PackToR_64f_t icvDFTInv_PackToR_64f_p = 0;
726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*icvDCTFwdInitAlloc_32f_t icvDCTFwdInitAlloc_32f_p = 0;
746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvDCTFwdFree_32f_t icvDCTFwdFree_32f_p = 0;
756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvDCTFwdGetBufSize_32f_t icvDCTFwdGetBufSize_32f_p = 0;
766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvDCTFwd_32f_t icvDCTFwd_32f_p = 0;
776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvDCTInvInitAlloc_32f_t icvDCTInvInitAlloc_32f_p = 0;
796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvDCTInvFree_32f_t icvDCTInvFree_32f_p = 0;
806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvDCTInvGetBufSize_32f_t icvDCTInvGetBufSize_32f_p = 0;
816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvDCTInv_32f_t icvDCTInv_32f_p = 0;
826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvDCTFwdInitAlloc_64f_t icvDCTFwdInitAlloc_64f_p = 0;
846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvDCTFwdFree_64f_t icvDCTFwdFree_64f_p = 0;
856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvDCTFwdGetBufSize_64f_t icvDCTFwdGetBufSize_64f_p = 0;
866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvDCTFwd_64f_t icvDCTFwd_64f_p = 0;
876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvDCTInvInitAlloc_64f_t icvDCTInvInitAlloc_64f_p = 0;
896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvDCTInvFree_64f_t icvDCTInvFree_64f_p = 0;
906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvDCTInvGetBufSize_64f_t icvDCTInvGetBufSize_64f_p = 0;
916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvDCTInv_64f_t icvDCTInv_64f_p = 0;*/
926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/****************************************************************************************\
946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                               Discrete Fourier Transform
956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn\****************************************************************************************/
966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define CV_MAX_LOCAL_DFT_SIZE  (1 << 15)
986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic const uchar log2tab[] = { 0, 0, 1, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0 };
1006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic int icvlog2( int n )
1016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
1026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int m = 0;
1036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int f = (n >= (1 << 16))*16;
1046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    n >>= f;
1056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    m += f;
1066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    f = (n >= (1 << 8))*8;
1076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    n >>= f;
1086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    m += f;
1096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    f = (n >= (1 << 4))*4;
1106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    n >>= f;
1116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return m + f + log2tab[n];
1126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
1136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic unsigned char icvRevTable[] =
1156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
1166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  0x00,0x80,0x40,0xc0,0x20,0xa0,0x60,0xe0,0x10,0x90,0x50,0xd0,0x30,0xb0,0x70,0xf0,
1176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  0x08,0x88,0x48,0xc8,0x28,0xa8,0x68,0xe8,0x18,0x98,0x58,0xd8,0x38,0xb8,0x78,0xf8,
1186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  0x04,0x84,0x44,0xc4,0x24,0xa4,0x64,0xe4,0x14,0x94,0x54,0xd4,0x34,0xb4,0x74,0xf4,
1196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  0x0c,0x8c,0x4c,0xcc,0x2c,0xac,0x6c,0xec,0x1c,0x9c,0x5c,0xdc,0x3c,0xbc,0x7c,0xfc,
1206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  0x02,0x82,0x42,0xc2,0x22,0xa2,0x62,0xe2,0x12,0x92,0x52,0xd2,0x32,0xb2,0x72,0xf2,
1216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  0x0a,0x8a,0x4a,0xca,0x2a,0xaa,0x6a,0xea,0x1a,0x9a,0x5a,0xda,0x3a,0xba,0x7a,0xfa,
1226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  0x06,0x86,0x46,0xc6,0x26,0xa6,0x66,0xe6,0x16,0x96,0x56,0xd6,0x36,0xb6,0x76,0xf6,
1236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  0x0e,0x8e,0x4e,0xce,0x2e,0xae,0x6e,0xee,0x1e,0x9e,0x5e,0xde,0x3e,0xbe,0x7e,0xfe,
1246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  0x01,0x81,0x41,0xc1,0x21,0xa1,0x61,0xe1,0x11,0x91,0x51,0xd1,0x31,0xb1,0x71,0xf1,
1256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  0x09,0x89,0x49,0xc9,0x29,0xa9,0x69,0xe9,0x19,0x99,0x59,0xd9,0x39,0xb9,0x79,0xf9,
1266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  0x05,0x85,0x45,0xc5,0x25,0xa5,0x65,0xe5,0x15,0x95,0x55,0xd5,0x35,0xb5,0x75,0xf5,
1276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  0x0d,0x8d,0x4d,0xcd,0x2d,0xad,0x6d,0xed,0x1d,0x9d,0x5d,0xdd,0x3d,0xbd,0x7d,0xfd,
1286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  0x03,0x83,0x43,0xc3,0x23,0xa3,0x63,0xe3,0x13,0x93,0x53,0xd3,0x33,0xb3,0x73,0xf3,
1296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  0x0b,0x8b,0x4b,0xcb,0x2b,0xab,0x6b,0xeb,0x1b,0x9b,0x5b,0xdb,0x3b,0xbb,0x7b,0xfb,
1306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  0x07,0x87,0x47,0xc7,0x27,0xa7,0x67,0xe7,0x17,0x97,0x57,0xd7,0x37,0xb7,0x77,0xf7,
1316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn  0x0f,0x8f,0x4f,0xcf,0x2f,0xaf,0x6f,0xef,0x1f,0x9f,0x5f,0xdf,0x3f,0xbf,0x7f,0xff
1326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn};
1336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic const double icvDxtTab[][2] =
1356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
1366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 1.00000000000000000, 0.00000000000000000 },
1376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{-1.00000000000000000, 0.00000000000000000 },
1386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 0.00000000000000000, 1.00000000000000000 },
1396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 0.70710678118654757, 0.70710678118654746 },
1406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 0.92387953251128674, 0.38268343236508978 },
1416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 0.98078528040323043, 0.19509032201612825 },
1426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 0.99518472667219693, 0.09801714032956060 },
1436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 0.99879545620517241, 0.04906767432741802 },
1446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 0.99969881869620425, 0.02454122852291229 },
1456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 0.99992470183914450, 0.01227153828571993 },
1466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 0.99998117528260111, 0.00613588464915448 },
1476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 0.99999529380957619, 0.00306795676296598 },
1486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 0.99999882345170188, 0.00153398018628477 },
1496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 0.99999970586288223, 0.00076699031874270 },
1506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 0.99999992646571789, 0.00038349518757140 },
1516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 0.99999998161642933, 0.00019174759731070 },
1526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 0.99999999540410733, 0.00009587379909598 },
1536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 0.99999999885102686, 0.00004793689960307 },
1546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 0.99999999971275666, 0.00002396844980842 },
1556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 0.99999999992818922, 0.00001198422490507 },
1566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 0.99999999998204725, 0.00000599211245264 },
1576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 0.99999999999551181, 0.00000299605622633 },
1586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 0.99999999999887801, 0.00000149802811317 },
1596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 0.99999999999971945, 0.00000074901405658 },
1606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 0.99999999999992983, 0.00000037450702829 },
1616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 0.99999999999998246, 0.00000018725351415 },
1626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 0.99999999999999567, 0.00000009362675707 },
1636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 0.99999999999999889, 0.00000004681337854 },
1646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 0.99999999999999978, 0.00000002340668927 },
1656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 0.99999999999999989, 0.00000001170334463 },
1666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 1.00000000000000000, 0.00000000585167232 },
1676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{ 1.00000000000000000, 0.00000000292583616 }
1686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn};
1696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define icvBitRev(i,shift) \
1716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn   ((int)((((unsigned)icvRevTable[(i)&255] << 24)+ \
1726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn           ((unsigned)icvRevTable[((i)>> 8)&255] << 16)+ \
1736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn           ((unsigned)icvRevTable[((i)>>16)&255] <<  8)+ \
1746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn           ((unsigned)icvRevTable[((i)>>24)])) >> (shift)))
1756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic int
1776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvDFTFactorize( int n, int* factors )
1786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
1796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int nf = 0, f, i, j;
1806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( n <= 5 )
1826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
1836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        factors[0] = n;
1846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return 1;
1856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
1866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    f = (((n - 1)^n)+1) >> 1;
1886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( f > 1 )
1896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
1906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        factors[nf++] = f;
1916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        n = f == n ? 1 : n/f;
1926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
1936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( f = 3; n > 1; )
1956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
1966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int d = n/f;
1976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( d*f == n )
1986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
1996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            factors[nf++] = f;
2006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            n = d;
2016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
2026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
2036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
2046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            f += 2;
2056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( f*f > n )
2066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                break;
2076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
2086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
2096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( n > 1 )
2116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        factors[nf++] = n;
2126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    f = (factors[0] & 1) == 0;
2146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = f; i < (nf+f)/2; i++ )
2156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_SWAP( factors[i], factors[nf-i-1+f], j );
2166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return nf;
2186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
2196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void
2216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvDFTInit( int n0, int nf, int* factors, int* itab, int elem_size, void* _wave, int inv_itab )
2226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
2236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int digits[34], radix[34];
2246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int n = factors[0], m = 0;
2256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int* itab0 = itab;
2266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i, j, k;
2276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvComplex64f w, w1;
2286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    double t;
2296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( n0 <= 5 )
2316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
2326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        itab[0] = 0;
2336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        itab[n0-1] = n0-1;
2346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( n0 != 4 )
2366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
2376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( i = 1; i < n0-1; i++ )
2386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                itab[i] = i;
2396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
2406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
2416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
2426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            itab[1] = 2;
2436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            itab[2] = 1;
2446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
2456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( n0 == 5 )
2466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
2476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( elem_size == sizeof(CvComplex64f) )
2486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ((CvComplex64f*)_wave)[0] = CvComplex64f(1.,0.);
2496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else
2506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ((CvComplex32f*)_wave)[0] = CvComplex32f(1.f,0.f);
2516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
2526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( n0 != 4 )
2536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            return;
2546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        m = 2;
2556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
2566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
2576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
2586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn	// radix[] is initialized from index 'nf' down to zero
2596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        assert (nf < 34);
2606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        radix[nf] = 1;
2616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        digits[nf] = 0;
2626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < nf; i++ )
2636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
2646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            digits[i] = 0;
2656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            radix[nf-i-1] = radix[nf-i]*factors[nf-i-1];
2666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
2676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( inv_itab && factors[0] != factors[nf-1] )
2696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            itab = (int*)_wave;
2706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( (n & 1) == 0 )
2726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
2736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int a = radix[1], na2 = n*a>>1, na4 = na2 >> 1;
2746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            m = icvlog2(n);
2756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( n <= 2  )
2776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
2786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                itab[0] = 0;
2796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                itab[1] = na2;
2806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
2816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else if( n <= 256 )
2826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
2836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int shift = 10 - m;
2846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( i = 0; i <= n - 4; i += 4 )
2856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
2866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    j = (icvRevTable[i>>2]>>shift)*a;
2876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    itab[i] = j;
2886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    itab[i+1] = j + na2;
2896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    itab[i+2] = j + na4;
2906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    itab[i+3] = j + na2 + na4;
2916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
2926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
2936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else
2946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
2956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int shift = 34 - m;
2966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( i = 0; i < n; i += 4 )
2976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
2986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    int i4 = i >> 2;
2996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    j = icvBitRev(i4,shift)*a;
3006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    itab[i] = j;
3016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    itab[i+1] = j + na2;
3026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    itab[i+2] = j + na4;
3036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    itab[i+3] = j + na2 + na4;
3046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
3056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
3066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            digits[1]++;
3086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( nf >= 2 )
3106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
3116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( i = n, j = radix[2]; i < n0; )
3126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
3136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( k = 0; k < n; k++ )
3146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        itab[i+k] = itab[k] + j;
3156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( (i += n) >= n0 )
3166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        break;
3176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    j += radix[2];
3186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( k = 1; ++digits[k] >= factors[k]; k++ )
3196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
3206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        digits[k] = 0;
3216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        j += radix[k+2] - radix[k];
3226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
3236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
3246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
3256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
3266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
3276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
3286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( i = 0, j = 0;; )
3296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
3306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                itab[i] = j;
3316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( ++i >= n0 )
3326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    break;
3336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                j += radix[1];
3346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( k = 0; ++digits[k] >= factors[k]; k++ )
3356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
3366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    digits[k] = 0;
3376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    j += radix[k+2] - radix[k];
3386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
3396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
3406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
3416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( itab != itab0 )
3436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
3446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            itab0[0] = 0;
3456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( i = n0 & 1; i < n0; i += 2 )
3466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
3476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int k0 = itab[i];
3486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int k1 = itab[i+1];
3496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                itab0[k0] = i;
3506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                itab0[k1] = i+1;
3516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
3526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
3536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
3546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( (n0 & (n0-1)) == 0 )
3566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
3576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        w.re = w1.re = icvDxtTab[m][0];
3586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        w.im = w1.im = -icvDxtTab[m][1];
3596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
3606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
3616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
3626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        t = -CV_PI*2/n0;
3636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        w.im = w1.im = sin(t);
3646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        w.re = w1.re = sqrt(1. - w1.im*w1.im);
3656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
3666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    n = (n0+1)/2;
3676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( elem_size == sizeof(CvComplex64f) )
3696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
3706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvComplex64f* wave = (CvComplex64f*)_wave;
3716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        wave[0].re = 1.;
3736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        wave[0].im = 0.;
3746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( (n0 & 1) == 0 )
3766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
3776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            wave[n].re = -1.;
3786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            wave[n].im = 0;
3796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
3806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 1; i < n; i++ )
3826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
3836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            wave[i] = w;
3846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            wave[n0-i].re = w.re;
3856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            wave[n0-i].im = -w.im;
3866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            t = w.re*w1.re - w.im*w1.im;
3886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            w.im = w.re*w1.im + w.im*w1.re;
3896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            w.re = t;
3906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
3916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
3926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
3936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
3946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvComplex32f* wave = (CvComplex32f*)_wave;
3956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        assert( elem_size == sizeof(CvComplex32f) );
3966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        wave[0].re = 1.f;
3986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        wave[0].im = 0.f;
3996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( (n0 & 1) == 0 )
4016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
4026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            wave[n].re = -1.f;
4036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            wave[n].im = 0.f;
4046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
4056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 1; i < n; i++ )
4076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
4086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            wave[i].re = (float)w.re;
4096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            wave[i].im = (float)w.im;
4106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            wave[n0-i].re = (float)w.re;
4116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            wave[n0-i].im = (float)-w.im;
4126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            t = w.re*w1.re - w.im*w1.im;
4146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            w.im = w.re*w1.im + w.im*w1.re;
4156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            w.re = t;
4166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
4176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
4186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
4196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic const double icv_sin_120 = 0.86602540378443864676372317075294;
4226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic const double icv_sin_45 = 0.70710678118654752440084436210485;
4236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic const double icv_fft5_2 = 0.559016994374947424102293417182819;
4246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic const double icv_fft5_3 = -0.951056516295153572116439333379382;
4256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic const double icv_fft5_4 = -1.538841768587626701285145288018455;
4266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic const double icv_fft5_5 = 0.363271264002680442947733378740309;
4276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define ICV_DFT_NO_PERMUTE 2
4296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define ICV_DFT_COMPLEX_INPUT_OR_OUTPUT 4
4306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// mixed-radix complex discrete Fourier transform: double-precision version
4326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvStatus CV_STDCALL
4336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvDFT_64fc( const CvComplex64f* src, CvComplex64f* dst, int n,
4346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn             int nf, int* factors, const int* itab,
4356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn             const CvComplex64f* wave, int tab_size,
4366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn             const void* spec, CvComplex64f* buf,
4376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn             int flags, double scale )
4386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
4396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int n0 = n, f_idx, nx;
4406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int inv = flags & CV_DXT_INVERSE;
4416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int dw0 = tab_size, dw;
4426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i, j, k;
4436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvComplex64f t;
4446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int tab_step;
4456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( spec )
4476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
4486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        assert( icvDFTFwd_CToC_64fc_p != 0 && icvDFTInv_CToC_64fc_p != 0 );
4496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return !inv ?
4506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            icvDFTFwd_CToC_64fc_p( src, dst, spec, buf ):
4516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            icvDFTInv_CToC_64fc_p( src, dst, spec, buf );
4526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
4536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    tab_step = tab_size == n ? 1 : tab_size == n*2 ? 2 : tab_size/n;
4556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // 0. shuffle data
4576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( dst != src )
4586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
4596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        assert( (flags & ICV_DFT_NO_PERMUTE) == 0 );
4606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( !inv )
4616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
4626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( i = 0; i <= n - 2; i += 2, itab += 2*tab_step )
4636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
4646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int k0 = itab[0], k1 = itab[tab_step];
4656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                assert( (unsigned)k0 < (unsigned)n && (unsigned)k1 < (unsigned)n );
4666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                dst[i] = src[k0]; dst[i+1] = src[k1];
4676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
4686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( i < n )
4706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                dst[n-1] = src[n-1];
4716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
4726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
4736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
4746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( i = 0; i <= n - 2; i += 2, itab += 2*tab_step )
4756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
4766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int k0 = itab[0], k1 = itab[tab_step];
4776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                assert( (unsigned)k0 < (unsigned)n && (unsigned)k1 < (unsigned)n );
4786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                t.re = src[k0].re; t.im = -src[k0].im;
4796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                dst[i] = t;
4806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                t.re = src[k1].re; t.im = -src[k1].im;
4816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                dst[i+1] = t;
4826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
4836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( i < n )
4856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
4866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                t.re = src[n-1].re; t.im = -src[n-1].im;
4876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                dst[i] = t;
4886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
4896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
4906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
4916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
4926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
4936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( (flags & ICV_DFT_NO_PERMUTE) == 0 )
4946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
4956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( factors[0] != factors[nf-1] )
4966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                return CV_INPLACE_NOT_SUPPORTED_ERR;
4976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( nf == 1 )
4986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
4996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( (n & 3) == 0 )
5006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
5016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    int n2 = n/2;
5026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CvComplex64f* dsth = dst + n2;
5036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( i = 0; i < n2; i += 2, itab += tab_step*2 )
5056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
5066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        j = itab[0];
5076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        assert( (unsigned)j < (unsigned)n2 );
5086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        CV_SWAP(dst[i+1], dsth[j], t);
5106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        if( j > i )
5116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        {
5126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            CV_SWAP(dst[i], dst[j], t);
5136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            CV_SWAP(dsth[i+1], dsth[j+1], t);
5146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        }
5156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
5166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
5176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                // else do nothing
5186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
5196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else
5206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
5216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( i = 0; i < n; i++, itab += tab_step )
5226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
5236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    j = itab[0];
5246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    assert( (unsigned)j < (unsigned)n );
5256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( j > i )
5266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        CV_SWAP(dst[i], dst[j], t);
5276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
5286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
5296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
5306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( inv )
5326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
5336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( i = 0; i <= n - 2; i += 2 )
5346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
5356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                double t0 = -dst[i].im;
5366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                double t1 = -dst[i+1].im;
5376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                dst[i].im = t0; dst[i+1].im = t1;
5386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
5396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( i < n )
5416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                dst[n-1].im = -dst[n-1].im;
5426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
5436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
5446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    n = 1;
5466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // 1. power-2 transforms
5476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( (factors[0] & 1) == 0 )
5486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
5496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        // radix-4 transform
5506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( ; n*4 <= factors[0]; )
5516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
5526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            nx = n;
5536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            n *= 4;
5546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dw0 /= 4;
5556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( i = 0; i < n0; i += n )
5576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
5586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CvComplex64f* v0;
5596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CvComplex64f* v1;
5606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                double r0, i0, r1, i1, r2, i2, r3, i3, r4, i4;
5616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                v0 = dst + i;
5636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                v1 = v0 + nx*2;
5646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                r2 = v0[0].re; i2 = v0[0].im;
5666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                r1 = v0[nx].re; i1 = v0[nx].im;
5676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                r0 = r1 + r2; i0 = i1 + i2;
5696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                r2 -= r1; i2 -= i1;
5706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                i3 = v1[nx].re; r3 = v1[nx].im;
5726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                i4 = v1[0].re; r4 = v1[0].im;
5736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                r1 = i4 + i3; i1 = r4 + r3;
5756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                r3 = r4 - r3; i3 = i3 - i4;
5766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                v0[0].re = r0 + r1; v0[0].im = i0 + i1;
5786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                v1[0].re = r0 - r1; v1[0].im = i0 - i1;
5796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                v0[nx].re = r2 + r3; v0[nx].im = i2 + i3;
5806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                v1[nx].re = r2 - r3; v1[nx].im = i2 - i3;
5816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( j = 1, dw = dw0; j < nx; j++, dw += dw0 )
5836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
5846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    v0 = dst + i + j;
5856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    v1 = v0 + nx*2;
5866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r2 = v0[nx].re*wave[dw*2].re - v0[nx].im*wave[dw*2].im;
5886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    i2 = v0[nx].re*wave[dw*2].im + v0[nx].im*wave[dw*2].re;
5896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r0 = v1[0].re*wave[dw].im + v1[0].im*wave[dw].re;
5906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    i0 = v1[0].re*wave[dw].re - v1[0].im*wave[dw].im;
5916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r3 = v1[nx].re*wave[dw*3].im + v1[nx].im*wave[dw*3].re;
5926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    i3 = v1[nx].re*wave[dw*3].re - v1[nx].im*wave[dw*3].im;
5936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r1 = i0 + i3; i1 = r0 + r3;
5956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r3 = r0 - r3; i3 = i3 - i0;
5966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r4 = v0[0].re; i4 = v0[0].im;
5976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r0 = r4 + r2; i0 = i4 + i2;
5996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r2 = r4 - r2; i2 = i4 - i2;
6006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    v0[0].re = r0 + r1; v0[0].im = i0 + i1;
6026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    v1[0].re = r0 - r1; v1[0].im = i0 - i1;
6036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    v0[nx].re = r2 + r3; v0[nx].im = i2 + i3;
6046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    v1[nx].re = r2 - r3; v1[nx].im = i2 - i3;
6056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
6066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
6076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
6086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( ; n < factors[0]; )
6106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
6116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            // do the remaining radix-2 transform
6126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            nx = n;
6136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            n *= 2;
6146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dw0 /= 2;
6156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( i = 0; i < n0; i += n )
6176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
6186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CvComplex64f* v = dst + i;
6196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                double r0 = v[0].re + v[nx].re;
6206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                double i0 = v[0].im + v[nx].im;
6216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                double r1 = v[0].re - v[nx].re;
6226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                double i1 = v[0].im - v[nx].im;
6236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                v[0].re = r0; v[0].im = i0;
6246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                v[nx].re = r1; v[nx].im = i1;
6256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( j = 1, dw = dw0; j < nx; j++, dw += dw0 )
6276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
6286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    v = dst + i + j;
6296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r1 = v[nx].re*wave[dw].re - v[nx].im*wave[dw].im;
6306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    i1 = v[nx].im*wave[dw].re + v[nx].re*wave[dw].im;
6316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r0 = v[0].re; i0 = v[0].im;
6326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    v[0].re = r0 + r1; v[0].im = i0 + i1;
6346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    v[nx].re = r0 - r1; v[nx].im = i0 - i1;
6356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
6366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
6376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
6386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
6396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // 2. all the other transforms
6416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( f_idx = (factors[0]&1) ? 0 : 1; f_idx < nf; f_idx++ )
6426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
6436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int factor = factors[f_idx];
6446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        nx = n;
6456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        n *= factor;
6466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dw0 /= factor;
6476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( factor == 3 )
6496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
6506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            // radix-3
6516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( i = 0; i < n0; i += n )
6526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
6536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CvComplex64f* v = dst + i;
6546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                double r1 = v[nx].re + v[nx*2].re;
6566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                double i1 = v[nx].im + v[nx*2].im;
6576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                double r0 = v[0].re;
6586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                double i0 = v[0].im;
6596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                double r2 = icv_sin_120*(v[nx].im - v[nx*2].im);
6606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                double i2 = icv_sin_120*(v[nx*2].re - v[nx].re);
6616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                v[0].re = r0 + r1; v[0].im = i0 + i1;
6626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                r0 -= 0.5*r1; i0 -= 0.5*i1;
6636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                v[nx].re = r0 + r2; v[nx].im = i0 + i2;
6646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                v[nx*2].re = r0 - r2; v[nx*2].im = i0 - i2;
6656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( j = 1, dw = dw0; j < nx; j++, dw += dw0 )
6676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
6686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    v = dst + i + j;
6696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r0 = v[nx].re*wave[dw].re - v[nx].im*wave[dw].im;
6706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    i0 = v[nx].re*wave[dw].im + v[nx].im*wave[dw].re;
6716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    i2 = v[nx*2].re*wave[dw*2].re - v[nx*2].im*wave[dw*2].im;
6726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r2 = v[nx*2].re*wave[dw*2].im + v[nx*2].im*wave[dw*2].re;
6736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r1 = r0 + i2; i1 = i0 + r2;
6746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r2 = icv_sin_120*(i0 - r2); i2 = icv_sin_120*(i2 - r0);
6766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r0 = v[0].re; i0 = v[0].im;
6776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    v[0].re = r0 + r1; v[0].im = i0 + i1;
6786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r0 -= 0.5*r1; i0 -= 0.5*i1;
6796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    v[nx].re = r0 + r2; v[nx].im = i0 + i2;
6806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    v[nx*2].re = r0 - r2; v[nx*2].im = i0 - i2;
6816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
6826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
6836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
6846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else if( factor == 5 )
6856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
6866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            // radix-5
6876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( i = 0; i < n0; i += n )
6886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
6896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( j = 0, dw = 0; j < nx; j++, dw += dw0 )
6906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
6916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CvComplex64f* v0 = dst + i + j;
6926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CvComplex64f* v1 = v0 + nx*2;
6936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CvComplex64f* v2 = v1 + nx*2;
6946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    double r0, i0, r1, i1, r2, i2, r3, i3, r4, i4, r5, i5;
6966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r3 = v0[nx].re*wave[dw].re - v0[nx].im*wave[dw].im;
6986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    i3 = v0[nx].re*wave[dw].im + v0[nx].im*wave[dw].re;
6996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r2 = v2[0].re*wave[dw*4].re - v2[0].im*wave[dw*4].im;
7006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    i2 = v2[0].re*wave[dw*4].im + v2[0].im*wave[dw*4].re;
7016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r1 = r3 + r2; i1 = i3 + i2;
7036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r3 -= r2; i3 -= i2;
7046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r4 = v1[nx].re*wave[dw*3].re - v1[nx].im*wave[dw*3].im;
7066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    i4 = v1[nx].re*wave[dw*3].im + v1[nx].im*wave[dw*3].re;
7076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r0 = v1[0].re*wave[dw*2].re - v1[0].im*wave[dw*2].im;
7086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    i0 = v1[0].re*wave[dw*2].im + v1[0].im*wave[dw*2].re;
7096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r2 = r4 + r0; i2 = i4 + i0;
7116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r4 -= r0; i4 -= i0;
7126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r0 = v0[0].re; i0 = v0[0].im;
7146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r5 = r1 + r2; i5 = i1 + i2;
7156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    v0[0].re = r0 + r5; v0[0].im = i0 + i5;
7176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r0 -= 0.25*r5; i0 -= 0.25*i5;
7196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r1 = icv_fft5_2*(r1 - r2); i1 = icv_fft5_2*(i1 - i2);
7206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r2 = -icv_fft5_3*(i3 + i4); i2 = icv_fft5_3*(r3 + r4);
7216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    i3 *= -icv_fft5_5; r3 *= icv_fft5_5;
7236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    i4 *= -icv_fft5_4; r4 *= icv_fft5_4;
7246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r5 = r2 + i3; i5 = i2 + r3;
7266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r2 -= i4; i2 -= r4;
7276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r3 = r0 + r1; i3 = i0 + i1;
7296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r0 -= r1; i0 -= i1;
7306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    v0[nx].re = r3 + r2; v0[nx].im = i3 + i2;
7326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    v2[0].re = r3 - r2; v2[0].im = i3 - i2;
7336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    v1[0].re = r0 + r5; v1[0].im = i0 + i5;
7356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    v1[nx].re = r0 - r5; v1[nx].im = i0 - i5;
7366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
7376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
7386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
7396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
7406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
7416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            // radix-"factor" - an odd number
7426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int p, q, factor2 = (factor - 1)/2;
7436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int d, dd, dw_f = tab_size/factor;
7446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CvComplex64f* a = buf;
7456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CvComplex64f* b = buf + factor2;
7466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( i = 0; i < n0; i += n )
7486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
7496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( j = 0, dw = 0; j < nx; j++, dw += dw0 )
7506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
7516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CvComplex64f* v = dst + i + j;
7526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CvComplex64f v_0 = v[0];
7536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CvComplex64f vn_0 = v_0;
7546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( j == 0 )
7566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
7576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        for( p = 1, k = nx; p <= factor2; p++, k += nx )
7586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        {
7596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            double r0 = v[k].re + v[n-k].re;
7606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            double i0 = v[k].im - v[n-k].im;
7616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            double r1 = v[k].re - v[n-k].re;
7626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            double i1 = v[k].im + v[n-k].im;
7636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            vn_0.re += r0; vn_0.im += i1;
7656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            a[p-1].re = r0; a[p-1].im = i0;
7666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            b[p-1].re = r1; b[p-1].im = i1;
7676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        }
7686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
7696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    else
7706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
7716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        const CvComplex64f* wave_ = wave + dw*factor;
7726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        d = dw;
7736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        for( p = 1, k = nx; p <= factor2; p++, k += nx, d += dw )
7756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        {
7766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            double r2 = v[k].re*wave[d].re - v[k].im*wave[d].im;
7776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            double i2 = v[k].re*wave[d].im + v[k].im*wave[d].re;
7786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            double r1 = v[n-k].re*wave_[-d].re - v[n-k].im*wave_[-d].im;
7806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            double i1 = v[n-k].re*wave_[-d].im + v[n-k].im*wave_[-d].re;
7816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            double r0 = r2 + r1;
7836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            double i0 = i2 - i1;
7846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            r1 = r2 - r1;
7856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            i1 = i2 + i1;
7866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            vn_0.re += r0; vn_0.im += i1;
7886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            a[p-1].re = r0; a[p-1].im = i0;
7896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            b[p-1].re = r1; b[p-1].im = i1;
7906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        }
7916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
7926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    v[0] = vn_0;
7946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( p = 1, k = nx; p <= factor2; p++, k += nx )
7966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
7976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        CvComplex64f s0 = v_0, s1 = v_0;
7986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        d = dd = dw_f*p;
7996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        for( q = 0; q < factor2; q++ )
8016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        {
8026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            double r0 = wave[d].re * a[q].re;
8036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            double i0 = wave[d].im * a[q].im;
8046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            double r1 = wave[d].re * b[q].im;
8056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            double i1 = wave[d].im * b[q].re;
8066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            s1.re += r0 + i0; s0.re += r0 - i0;
8086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            s1.im += r1 - i1; s0.im += r1 + i1;
8096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            d += dd;
8116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            d -= -(d >= tab_size) & tab_size;
8126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        }
8136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        v[k] = s0;
8156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        v[n-k] = s1;
8166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
8176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
8186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
8196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
8206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
8216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( fabs(scale - 1.) > DBL_EPSILON )
8236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
8246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        double re_scale = scale, im_scale = scale;
8256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( inv )
8266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            im_scale = -im_scale;
8276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < n0; i++ )
8296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
8306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            double t0 = dst[i].re*re_scale;
8316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            double t1 = dst[i].im*im_scale;
8326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[i].re = t0;
8336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[i].im = t1;
8346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
8356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
8366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else if( inv )
8376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
8386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i <= n0 - 2; i += 2 )
8396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
8406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            double t0 = -dst[i].im;
8416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            double t1 = -dst[i+1].im;
8426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[i].im = t0;
8436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[i+1].im = t1;
8446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
8456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( i < n0 )
8476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[n0-1].im = -dst[n0-1].im;
8486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
8496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return CV_OK;
8516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
8526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// mixed-radix complex discrete Fourier transform: single-precision version
8556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvStatus CV_STDCALL
8566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvDFT_32fc( const CvComplex32f* src, CvComplex32f* dst, int n,
8576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn             int nf, int* factors, const int* itab,
8586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn             const CvComplex32f* wave, int tab_size,
8596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn             const void* spec, CvComplex32f* buf,
8606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn             int flags, double scale )
8616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
8626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int n0 = n, f_idx, nx;
8636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int inv = flags & CV_DXT_INVERSE;
8646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int dw0 = tab_size, dw;
8656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i, j, k;
8666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvComplex32f t;
8676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int tab_step = tab_size == n ? 1 : tab_size == n*2 ? 2 : tab_size/n;
8686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( spec )
8706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
8716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        assert( icvDFTFwd_CToC_32fc_p != 0 && icvDFTInv_CToC_32fc_p != 0 );
8726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return !inv ?
8736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            icvDFTFwd_CToC_32fc_p( src, dst, spec, buf ):
8746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            icvDFTInv_CToC_32fc_p( src, dst, spec, buf );
8756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
8766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // 0. shuffle data
8786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( dst != src )
8796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
8806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        assert( (flags & ICV_DFT_NO_PERMUTE) == 0 );
8816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( !inv )
8826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
8836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( i = 0; i <= n - 2; i += 2, itab += 2*tab_step )
8846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
8856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int k0 = itab[0], k1 = itab[tab_step];
8866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                assert( (unsigned)k0 < (unsigned)n && (unsigned)k1 < (unsigned)n );
8876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                dst[i] = src[k0]; dst[i+1] = src[k1];
8886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
8896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( i < n )
8916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                dst[n-1] = src[n-1];
8926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
8936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
8946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
8956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( i = 0; i <= n - 2; i += 2, itab += 2*tab_step )
8966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
8976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int k0 = itab[0], k1 = itab[tab_step];
8986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                assert( (unsigned)k0 < (unsigned)n && (unsigned)k1 < (unsigned)n );
8996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                t.re = src[k0].re; t.im = -src[k0].im;
9006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                dst[i] = t;
9016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                t.re = src[k1].re; t.im = -src[k1].im;
9026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                dst[i+1] = t;
9036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
9046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( i < n )
9066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
9076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                t.re = src[n-1].re; t.im = -src[n-1].im;
9086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                dst[i] = t;
9096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
9106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
9116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
9126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
9136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
9146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( (flags & ICV_DFT_NO_PERMUTE) == 0 )
9156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
9166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( factors[0] != factors[nf-1] )
9176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                return CV_INPLACE_NOT_SUPPORTED_ERR;
9186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( nf == 1 )
9196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
9206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( (n & 3) == 0 )
9216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
9226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    int n2 = n/2;
9236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CvComplex32f* dsth = dst + n2;
9246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( i = 0; i < n2; i += 2, itab += tab_step*2 )
9266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
9276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        j = itab[0];
9286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        assert( (unsigned)j < (unsigned)n2 );
9296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        CV_SWAP(dst[i+1], dsth[j], t);
9316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        if( j > i )
9326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        {
9336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            CV_SWAP(dst[i], dst[j], t);
9346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            CV_SWAP(dsth[i+1], dsth[j+1], t);
9356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        }
9366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
9376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
9386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                // else do nothing
9396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
9406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else
9416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
9426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( i = 0;
9436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                i < n;
9446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                i++)
9456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
9466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    j = itab[0];
9476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    assert( (unsigned)j < (unsigned)n );
9486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( j > i )
9496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        CV_SWAP(dst[i], dst[j], t);
9506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    itab += tab_step;
9516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
9526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
9536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
9546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( inv )
9566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
9576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            // conjugate the vector - i.e. invert sign of the imaginary part
9586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int* idst = (int*)dst;
9596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( i = 0; i <= n - 2; i += 2 )
9606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
9616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int t0 = idst[i*2+1] ^ 0x80000000;
9626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int t1 = idst[i*2+3] ^ 0x80000000;
9636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                idst[i*2+1] = t0; idst[i*2+3] = t1;
9646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
9656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( i < n )
9676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                idst[2*i+1] ^= 0x80000000;
9686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
9696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
9706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    n = 1;
9726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // 1. power-2 transforms
9736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( (factors[0] & 1) == 0 )
9746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
9756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        // radix-4 transform
9766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( ; n*4 <= factors[0]; )
9776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
9786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            nx = n;
9796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            n *= 4;
9806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dw0 /= 4;
9816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( i = 0; i < n0; i += n )
9836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
9846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CvComplex32f* v0;
9856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CvComplex32f* v1;
9866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                double r0, i0, r1, i1, r2, i2, r3, i3, r4, i4;
9876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                v0 = dst + i;
9896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                v1 = v0 + nx*2;
9906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                r2 = v0[0].re; i2 = v0[0].im;
9926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                r1 = v0[nx].re; i1 = v0[nx].im;
9936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                r0 = r1 + r2; i0 = i1 + i2;
9956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                r2 -= r1; i2 -= i1;
9966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                i3 = v1[nx].re; r3 = v1[nx].im;
9986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                i4 = v1[0].re; r4 = v1[0].im;
9996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                r1 = i4 + i3; i1 = r4 + r3;
10016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                r3 = r4 - r3; i3 = i3 - i4;
10026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                v0[0].re = (float)(r0 + r1); v0[0].im = (float)(i0 + i1);
10046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                v1[0].re = (float)(r0 - r1); v1[0].im = (float)(i0 - i1);
10056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                v0[nx].re = (float)(r2 + r3); v0[nx].im = (float)(i2 + i3);
10066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                v1[nx].re = (float)(r2 - r3); v1[nx].im = (float)(i2 - i3);
10076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( j = 1, dw = dw0; j < nx; j++, dw += dw0 )
10096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
10106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    v0 = dst + i + j;
10116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    v1 = v0 + nx*2;
10126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r2 = v0[nx].re*wave[dw*2].re - v0[nx].im*wave[dw*2].im;
10146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    i2 = v0[nx].re*wave[dw*2].im + v0[nx].im*wave[dw*2].re;
10156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r0 = v1[0].re*wave[dw].im + v1[0].im*wave[dw].re;
10166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    i0 = v1[0].re*wave[dw].re - v1[0].im*wave[dw].im;
10176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r3 = v1[nx].re*wave[dw*3].im + v1[nx].im*wave[dw*3].re;
10186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    i3 = v1[nx].re*wave[dw*3].re - v1[nx].im*wave[dw*3].im;
10196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r1 = i0 + i3; i1 = r0 + r3;
10216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r3 = r0 - r3; i3 = i3 - i0;
10226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r4 = v0[0].re; i4 = v0[0].im;
10236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r0 = r4 + r2; i0 = i4 + i2;
10256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r2 = r4 - r2; i2 = i4 - i2;
10266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    v0[0].re = (float)(r0 + r1); v0[0].im = (float)(i0 + i1);
10286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    v1[0].re = (float)(r0 - r1); v1[0].im = (float)(i0 - i1);
10296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    v0[nx].re = (float)(r2 + r3); v0[nx].im = (float)(i2 + i3);
10306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    v1[nx].re = (float)(r2 - r3); v1[nx].im = (float)(i2 - i3);
10316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
10326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
10336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
10346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( ; n < factors[0]; )
10366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
10376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            // do the remaining radix-2 transform
10386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            nx = n;
10396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            n *= 2;
10406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dw0 /= 2;
10416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( i = 0; i < n0; i += n )
10436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
10446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CvComplex32f* v = dst + i;
10456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                double r0 = v[0].re + v[nx].re;
10466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                double i0 = v[0].im + v[nx].im;
10476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                double r1 = v[0].re - v[nx].re;
10486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                double i1 = v[0].im - v[nx].im;
10496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                v[0].re = (float)r0; v[0].im = (float)i0;
10506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                v[nx].re = (float)r1; v[nx].im = (float)i1;
10516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( j = 1, dw = dw0; j < nx; j++, dw += dw0 )
10536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
10546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    v = dst + i + j;
10556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r1 = v[nx].re*wave[dw].re - v[nx].im*wave[dw].im;
10566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    i1 = v[nx].im*wave[dw].re + v[nx].re*wave[dw].im;
10576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r0 = v[0].re; i0 = v[0].im;
10586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    v[0].re = (float)(r0 + r1); v[0].im = (float)(i0 + i1);
10606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    v[nx].re = (float)(r0 - r1); v[nx].im = (float)(i0 - i1);
10616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
10626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
10636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
10646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
10656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // 2. all the other transforms
10676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( f_idx = (factors[0]&1) ? 0 : 1; f_idx < nf; f_idx++ )
10686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
10696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int factor = factors[f_idx];
10706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        nx = n;
10716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        n *= factor;
10726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dw0 /= factor;
10736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( factor == 3 )
10756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
10766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            // radix-3
10776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( i = 0; i < n0; i += n )
10786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
10796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CvComplex32f* v = dst + i;
10806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                double r1 = v[nx].re + v[nx*2].re;
10826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                double i1 = v[nx].im + v[nx*2].im;
10836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                double r0 = v[0].re;
10846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                double i0 = v[0].im;
10856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                double r2 = icv_sin_120*(v[nx].im - v[nx*2].im);
10866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                double i2 = icv_sin_120*(v[nx*2].re - v[nx].re);
10876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                v[0].re = (float)(r0 + r1); v[0].im = (float)(i0 + i1);
10886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                r0 -= 0.5*r1; i0 -= 0.5*i1;
10896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                v[nx].re = (float)(r0 + r2); v[nx].im = (float)(i0 + i2);
10906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                v[nx*2].re = (float)(r0 - r2); v[nx*2].im = (float)(i0 - i2);
10916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( j = 1, dw = dw0; j < nx; j++, dw += dw0 )
10936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
10946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    v = dst + i + j;
10956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r0 = v[nx].re*wave[dw].re - v[nx].im*wave[dw].im;
10966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    i0 = v[nx].re*wave[dw].im + v[nx].im*wave[dw].re;
10976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    i2 = v[nx*2].re*wave[dw*2].re - v[nx*2].im*wave[dw*2].im;
10986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r2 = v[nx*2].re*wave[dw*2].im + v[nx*2].im*wave[dw*2].re;
10996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r1 = r0 + i2; i1 = i0 + r2;
11006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r2 = icv_sin_120*(i0 - r2); i2 = icv_sin_120*(i2 - r0);
11026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r0 = v[0].re; i0 = v[0].im;
11036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    v[0].re = (float)(r0 + r1); v[0].im = (float)(i0 + i1);
11046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r0 -= 0.5*r1; i0 -= 0.5*i1;
11056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    v[nx].re = (float)(r0 + r2); v[nx].im = (float)(i0 + i2);
11066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    v[nx*2].re = (float)(r0 - r2); v[nx*2].im = (float)(i0 - i2);
11076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
11086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
11096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
11106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else if( factor == 5 )
11116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
11126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            // radix-5
11136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( i = 0; i < n0; i += n )
11146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
11156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( j = 0, dw = 0; j < nx; j++, dw += dw0 )
11166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
11176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CvComplex32f* v0 = dst + i + j;
11186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CvComplex32f* v1 = v0 + nx*2;
11196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CvComplex32f* v2 = v1 + nx*2;
11206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    double r0, i0, r1, i1, r2, i2, r3, i3, r4, i4, r5, i5;
11226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r3 = v0[nx].re*wave[dw].re - v0[nx].im*wave[dw].im;
11246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    i3 = v0[nx].re*wave[dw].im + v0[nx].im*wave[dw].re;
11256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r2 = v2[0].re*wave[dw*4].re - v2[0].im*wave[dw*4].im;
11266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    i2 = v2[0].re*wave[dw*4].im + v2[0].im*wave[dw*4].re;
11276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r1 = r3 + r2; i1 = i3 + i2;
11296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r3 -= r2; i3 -= i2;
11306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r4 = v1[nx].re*wave[dw*3].re - v1[nx].im*wave[dw*3].im;
11326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    i4 = v1[nx].re*wave[dw*3].im + v1[nx].im*wave[dw*3].re;
11336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r0 = v1[0].re*wave[dw*2].re - v1[0].im*wave[dw*2].im;
11346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    i0 = v1[0].re*wave[dw*2].im + v1[0].im*wave[dw*2].re;
11356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r2 = r4 + r0; i2 = i4 + i0;
11376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r4 -= r0; i4 -= i0;
11386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r0 = v0[0].re; i0 = v0[0].im;
11406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r5 = r1 + r2; i5 = i1 + i2;
11416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    v0[0].re = (float)(r0 + r5); v0[0].im = (float)(i0 + i5);
11436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r0 -= 0.25*r5; i0 -= 0.25*i5;
11456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r1 = icv_fft5_2*(r1 - r2); i1 = icv_fft5_2*(i1 - i2);
11466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r2 = -icv_fft5_3*(i3 + i4); i2 = icv_fft5_3*(r3 + r4);
11476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    i3 *= -icv_fft5_5; r3 *= icv_fft5_5;
11496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    i4 *= -icv_fft5_4; r4 *= icv_fft5_4;
11506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r5 = r2 + i3; i5 = i2 + r3;
11526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r2 -= i4; i2 -= r4;
11536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r3 = r0 + r1; i3 = i0 + i1;
11556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r0 -= r1; i0 -= i1;
11566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    v0[nx].re = (float)(r3 + r2); v0[nx].im = (float)(i3 + i2);
11586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    v2[0].re = (float)(r3 - r2); v2[0].im = (float)(i3 - i2);
11596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    v1[0].re = (float)(r0 + r5); v1[0].im = (float)(i0 + i5);
11616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    v1[nx].re = (float)(r0 - r5); v1[nx].im = (float)(i0 - i5);
11626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
11636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
11646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
11656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
11666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
11676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            // radix-"factor" - an odd number
11686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int p, q, factor2 = (factor - 1)/2;
11696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int d, dd, dw_f = tab_size/factor;
11706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CvComplex32f* a = buf;
11716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CvComplex32f* b = buf + factor2;
11726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( i = 0; i < n0; i += n )
11746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
11756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( j = 0, dw = 0; j < nx; j++, dw += dw0 )
11766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
11776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CvComplex32f* v = dst + i + j;
11786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CvComplex32f v_0 = v[0];
11796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CvComplex64f vn_0(v_0);
11806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( j == 0 )
11826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
11836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        for( p = 1, k = nx; p <= factor2; p++, k += nx )
11846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        {
11856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            double r0 = v[k].re + v[n-k].re;
11866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            double i0 = v[k].im - v[n-k].im;
11876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            double r1 = v[k].re - v[n-k].re;
11886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            double i1 = v[k].im + v[n-k].im;
11896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            vn_0.re += r0; vn_0.im += i1;
11916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            a[p-1].re = (float)r0; a[p-1].im = (float)i0;
11926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            b[p-1].re = (float)r1; b[p-1].im = (float)i1;
11936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        }
11946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
11956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    else
11966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
11976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        const CvComplex32f* wave_ = wave + dw*factor;
11986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        d = dw;
11996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        for( p = 1, k = nx; p <= factor2; p++, k += nx, d += dw )
12016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        {
12026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            double r2 = v[k].re*wave[d].re - v[k].im*wave[d].im;
12036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            double i2 = v[k].re*wave[d].im + v[k].im*wave[d].re;
12046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            double r1 = v[n-k].re*wave_[-d].re - v[n-k].im*wave_[-d].im;
12066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            double i1 = v[n-k].re*wave_[-d].im + v[n-k].im*wave_[-d].re;
12076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            double r0 = r2 + r1;
12096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            double i0 = i2 - i1;
12106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            r1 = r2 - r1;
12116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            i1 = i2 + i1;
12126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            vn_0.re += r0; vn_0.im += i1;
12146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            a[p-1].re = (float)r0; a[p-1].im = (float)i0;
12156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            b[p-1].re = (float)r1; b[p-1].im = (float)i1;
12166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        }
12176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
12186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    v[0].re = (float)vn_0.re;
12206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    v[0].im = (float)vn_0.im;
12216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( p = 1, k = nx; p <= factor2; p++, k += nx )
12236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
12246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        CvComplex64f s0(v_0), s1 = s0;
12256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        d = dd = dw_f*p;
12266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        for( q = 0; q < factor2; q++ )
12286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        {
12296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            double r0 = wave[d].re * a[q].re;
12306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            double i0 = wave[d].im * a[q].im;
12316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            double r1 = wave[d].re * b[q].im;
12326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            double i1 = wave[d].im * b[q].re;
12336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            s1.re += r0 + i0; s0.re += r0 - i0;
12356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            s1.im += r1 - i1; s0.im += r1 + i1;
12366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            d += dd;
12386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            d -= -(d >= tab_size) & tab_size;
12396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        }
12406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        v[k].re = (float)s0.re;
12426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        v[k].im = (float)s0.im;
12436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        v[n-k].re = (float)s1.re;
12446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        v[n-k].im = (float)s1.im;
12456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
12466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
12476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
12486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
12496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
12506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( fabs(scale - 1.) > DBL_EPSILON )
12526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
12536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        double re_scale = scale, im_scale = scale;
12546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( inv )
12556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            im_scale = -im_scale;
12566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < n0; i++ )
12586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
12596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            double t0 = dst[i].re*re_scale;
12606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            double t1 = dst[i].im*im_scale;
12616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[i].re = (float)t0;
12626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[i].im = (float)t1;
12636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
12646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
12656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else if( inv )
12666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
12676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i <= n0 - 2; i += 2 )
12686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
12696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            double t0 = -dst[i].im;
12706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            double t1 = -dst[i+1].im;
12716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[i].im = (float)t0;
12726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[i+1].im = (float)t1;
12736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
12746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( i < n0 )
12766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[n0-1].im = -dst[n0-1].im;
12776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
12786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return CV_OK;
12806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
12816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* FFT of real vector
12846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn   output vector format:
12856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn     re(0), re(1), im(1), ... , re(n/2-1), im((n+1)/2-1) [, re((n+1)/2)] OR ...
12866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn     re(0), 0, re(1), im(1), ..., re(n/2-1), im((n+1)/2-1) [, re((n+1)/2), 0] */
12876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define ICV_REAL_DFT( flavor, datatype )                                \
12886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvStatus CV_STDCALL                                              \
12896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvRealDFT_##flavor( const datatype* src, datatype* dst,                \
12906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                     int n, int nf, int* factors, const int* itab,      \
12916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                     const CvComplex##flavor* wave, int tab_size,       \
12926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                     const void* spec, CvComplex##flavor* buf,          \
12936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                     int flags, double scale )                          \
12946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{                                                                       \
12956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int complex_output = (flags & ICV_DFT_COMPLEX_INPUT_OR_OUTPUT) != 0;\
12966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int j, n2 = n >> 1;                                                 \
12976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dst += complex_output;                                              \
12986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                        \
12996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( spec )                                                          \
13006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {                                                                   \
13016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        icvDFTFwd_RToPack_##flavor##_p( src, dst, spec, buf );          \
13026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        goto finalize;                                                  \
13036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }                                                                   \
13046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                        \
13056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    assert( tab_size == n );                                            \
13066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                        \
13076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( n == 1 )                                                        \
13086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {                                                                   \
13096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dst[0] = (datatype)(src[0]*scale);                              \
13106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }                                                                   \
13116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else if( n == 2 )                                                   \
13126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {                                                                   \
13136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        double t = (src[0] + src[1])*scale;                             \
13146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dst[1] = (datatype)((src[0] - src[1])*scale);                   \
13156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dst[0] = (datatype)t;                                           \
13166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }                                                                   \
13176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else if( n & 1 )                                                    \
13186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {                                                                   \
13196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dst -= complex_output;                                          \
13206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvComplex##flavor* _dst = (CvComplex##flavor*)dst;              \
13216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        _dst[0].re = (datatype)(src[0]*scale);                          \
13226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        _dst[0].im = 0;                                                 \
13236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( j = 1; j < n; j += 2 )                                     \
13246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                                               \
13256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            double t0 = src[itab[j]]*scale;                             \
13266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            double t1 = src[itab[j+1]]*scale;                           \
13276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            _dst[j].re = (datatype)t0;                                  \
13286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            _dst[j].im = 0;                                             \
13296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            _dst[j+1].re = (datatype)t1;                                \
13306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            _dst[j+1].im = 0;                                           \
13316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                                                               \
13326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        icvDFT_##flavor##c( _dst, _dst, n, nf, factors, itab, wave,     \
13336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            tab_size, 0, buf, ICV_DFT_NO_PERMUTE, 1. ); \
13346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( !complex_output )                                           \
13356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[1] = dst[0];                                            \
13366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_OK;                                                   \
13376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }                                                                   \
13386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else                                                                \
13396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {                                                                   \
13406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        double t0, t;                                                   \
13416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        double h1_re, h1_im, h2_re, h2_im;                              \
13426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        double scale2 = scale*0.5;                                      \
13436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        factors[0] >>= 1;                                               \
13446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                        \
13456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        icvDFT_##flavor##c( (CvComplex##flavor*)src,                    \
13466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            (CvComplex##flavor*)dst, n2,                \
13476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            nf - (factors[0] == 1),                     \
13486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            factors + (factors[0] == 1),                \
13496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            itab, wave, tab_size, 0, buf, 0, 1. );      \
13506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        factors[0] <<= 1;                                               \
13516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                        \
13526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        t = dst[0] - dst[1];                                            \
13536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dst[0] = (datatype)((dst[0] + dst[1])*scale);                   \
13546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dst[1] = (datatype)(t*scale);                                   \
13556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                        \
13566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        t0 = dst[n2];                                                   \
13576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        t = dst[n-1];                                                   \
13586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dst[n-1] = dst[1];                                              \
13596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                        \
13606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( j = 2, wave++; j < n2; j += 2, wave++ )                    \
13616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                                               \
13626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            /* calc odd */                                              \
13636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            h2_re = scale2*(dst[j+1] + t);                              \
13646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            h2_im = scale2*(dst[n-j] - dst[j]);                         \
13656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                        \
13666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            /* calc even */                                             \
13676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            h1_re = scale2*(dst[j] + dst[n-j]);                         \
13686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            h1_im = scale2*(dst[j+1] - t);                              \
13696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                        \
13706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            /* rotate */                                                \
13716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            t = h2_re*wave->re - h2_im*wave->im;                        \
13726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            h2_im = h2_re*wave->im + h2_im*wave->re;                    \
13736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            h2_re = t;                                                  \
13746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            t = dst[n-j-1];                                             \
13756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                        \
13766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[j-1] = (datatype)(h1_re + h2_re);                       \
13776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[n-j-1] = (datatype)(h1_re - h2_re);                     \
13786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[j] = (datatype)(h1_im + h2_im);                         \
13796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[n-j] = (datatype)(h2_im - h1_im);                       \
13806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                                                               \
13816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                        \
13826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( j <= n2 )                                                   \
13836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                                               \
13846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[n2-1] = (datatype)(t0*scale);                           \
13856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[n2] = (datatype)(-t*scale);                             \
13866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                                                               \
13876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }                                                                   \
13886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                        \
13896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennfinalize:                                                               \
13906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( complex_output )                                                \
13916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {                                                                   \
13926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dst[-1] = dst[0];                                               \
13936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dst[0] = 0;                                                     \
13946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( (n & 1) == 0 )                                              \
13956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[n] = 0;                                                 \
13966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }                                                                   \
13976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                        \
13986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return CV_OK;                                                       \
13996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
14006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* Inverse FFT of complex conjugate-symmetric vector
14036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn   input vector format:
14046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn      re[0], re[1], im[1], ... , re[n/2-1], im[n/2-1], re[n/2] OR
14056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn      re(0), 0, re(1), im(1), ..., re(n/2-1), im((n+1)/2-1) [, re((n+1)/2), 0] */
14066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define ICV_CCS_IDFT( flavor, datatype )                                \
14076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvStatus CV_STDCALL                                              \
14086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvCCSIDFT_##flavor( const datatype* src, datatype* dst,                \
14096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                     int n, int nf, int* factors, const int* itab,      \
14106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                     const CvComplex##flavor* wave, int tab_size,       \
14116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                     const void* spec, CvComplex##flavor* buf,          \
14126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                     int flags, double scale )                          \
14136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{                                                                       \
14146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int complex_input = (flags & ICV_DFT_COMPLEX_INPUT_OR_OUTPUT) != 0; \
14156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int j, k, n2 = (n+1) >> 1;                                          \
14166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    double save_s1 = 0.;                                                \
14176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    double t0, t1, t2, t3, t;                                           \
14186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                        \
14196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    assert( tab_size == n );                                            \
14206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                        \
14216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( complex_input )                                                 \
14226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {                                                                   \
14236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        assert( src != dst );                                           \
14246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        save_s1 = src[1];                                               \
14256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        ((datatype*)src)[1] = src[0];                                   \
14266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        src++;                                                          \
14276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }                                                                   \
14286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                        \
14296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( spec )                                                          \
14306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {                                                                   \
14316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        icvDFTInv_PackToR_##flavor##_p( src, dst, spec, buf );          \
14326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        goto finalize;                                                  \
14336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }                                                                   \
14346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                        \
14356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( n == 1 )                                                        \
14366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {                                                                   \
14376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dst[0] = (datatype)(src[0]*scale);                              \
14386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }                                                                   \
14396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else if( n == 2 )                                                   \
14406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {                                                                   \
14416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        t = (src[0] + src[1])*scale;                                    \
14426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dst[1] = (datatype)((src[0] - src[1])*scale);                   \
14436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dst[0] = (datatype)t;                                           \
14446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }                                                                   \
14456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else if( n & 1 )                                                    \
14466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {                                                                   \
14476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvComplex##flavor* _src = (CvComplex##flavor*)(src-1);          \
14486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvComplex##flavor* _dst = (CvComplex##flavor*)dst;              \
14496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                        \
14506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        _dst[0].re = src[0];                                            \
14516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        _dst[0].im = 0;                                                 \
14526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( j = 1; j < n2; j++ )                                       \
14536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                                               \
14546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int k0 = itab[j], k1 = itab[n-j];                           \
14556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            t0 = _src[j].re; t1 = _src[j].im;                           \
14566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            _dst[k0].re = (datatype)t0; _dst[k0].im = (datatype)-t1;    \
14576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            _dst[k1].re = (datatype)t0; _dst[k1].im = (datatype)t1;     \
14586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                                                               \
14596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                        \
14606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        icvDFT_##flavor##c( _dst, _dst, n, nf, factors, itab, wave,     \
14616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            tab_size, 0, buf, ICV_DFT_NO_PERMUTE, 1. ); \
14626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dst[0] = (datatype)(dst[0]*scale);                              \
14636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( j = 1; j < n; j += 2 )                                     \
14646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                                               \
14656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            t0 = dst[j*2]*scale;                                        \
14666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            t1 = dst[j*2+2]*scale;                                      \
14676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[j] = (datatype)t0;                                      \
14686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[j+1] = (datatype)t1;                                    \
14696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                                                               \
14706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }                                                                   \
14716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else                                                                \
14726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {                                                                   \
14736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int inplace = src == dst;                                       \
14746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        const CvComplex##flavor* w = wave;                              \
14756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                        \
14766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        t = src[1];                                                     \
14776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        t0 = (src[0] + src[n-1]);                                       \
14786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        t1 = (src[n-1] - src[0]);                                       \
14796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dst[0] = (datatype)t0;                                          \
14806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dst[1] = (datatype)t1;                                          \
14816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                        \
14826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( j = 2, w++; j < n2; j += 2, w++ )                          \
14836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                                               \
14846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            double h1_re, h1_im, h2_re, h2_im;                          \
14856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                        \
14866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            h1_re = (t + src[n-j-1]);                                   \
14876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            h1_im = (src[j] - src[n-j]);                                \
14886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                        \
14896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            h2_re = (t - src[n-j-1]);                                   \
14906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            h2_im = (src[j] + src[n-j]);                                \
14916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                        \
14926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            t = h2_re*w->re + h2_im*w->im;                              \
14936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            h2_im = h2_im*w->re - h2_re*w->im;                          \
14946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            h2_re = t;                                                  \
14956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                        \
14966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            t = src[j+1];                                               \
14976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            t0 = h1_re - h2_im;                                         \
14986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            t1 = -h1_im - h2_re;                                        \
14996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            t2 = h1_re + h2_im;                                         \
15006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            t3 = h1_im - h2_re;                                         \
15016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                        \
15026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( inplace )                                               \
15036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {                                                           \
15046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                dst[j] = (datatype)t0;                                  \
15056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                dst[j+1] = (datatype)t1;                                \
15066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                dst[n-j] = (datatype)t2;                                \
15076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                dst[n-j+1]= (datatype)t3;                               \
15086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }                                                           \
15096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else                                                        \
15106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {                                                           \
15116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int j2 = j >> 1;                                        \
15126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                k = itab[j2];                                           \
15136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                dst[k] = (datatype)t0;                                  \
15146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                dst[k+1] = (datatype)t1;                                \
15156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                k = itab[n2-j2];                                        \
15166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                dst[k] = (datatype)t2;                                  \
15176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                dst[k+1]= (datatype)t3;                                 \
15186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }                                                           \
15196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                                                               \
15206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                        \
15216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( j <= n2 )                                                   \
15226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                                               \
15236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            t0 = t*2;                                                   \
15246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            t1 = src[n2]*2;                                             \
15256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                        \
15266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( inplace )                                               \
15276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {                                                           \
15286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                dst[n2] = (datatype)t0;                                 \
15296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                dst[n2+1] = (datatype)t1;                               \
15306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }                                                           \
15316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else                                                        \
15326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {                                                           \
15336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                k = itab[n2];                                           \
15346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                dst[k*2] = (datatype)t0;                                \
15356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                dst[k*2+1] = (datatype)t1;                              \
15366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }                                                           \
15376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                                                               \
15386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                        \
15396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        factors[0] >>= 1;                                               \
15406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        icvDFT_##flavor##c( (CvComplex##flavor*)dst,                    \
15416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            (CvComplex##flavor*)dst, n2,                \
15426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            nf - (factors[0] == 1),                     \
15436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            factors + (factors[0] == 1), itab,          \
15446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            wave, tab_size, 0, buf,                     \
15456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            inplace ? 0 : ICV_DFT_NO_PERMUTE, 1. );     \
15466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        factors[0] <<= 1;                                               \
15476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                        \
15486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( j = 0; j < n; j += 2 )                                     \
15496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {                                                               \
15506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            t0 = dst[j]*scale;                                          \
15516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            t1 = dst[j+1]*(-scale);                                     \
15526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[j] = (datatype)t0;                                      \
15536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[j+1] = (datatype)t1;                                    \
15546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                                                               \
15556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }                                                                   \
15566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                        \
15576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennfinalize:                                                               \
15586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( complex_input )                                                 \
15596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        ((datatype*)src)[0] = (datatype)save_s1;                        \
15606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                        \
15616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return CV_OK;                                                       \
15626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
15636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_REAL_DFT( 64f, double )
15666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_CCS_IDFT( 64f, double )
15676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_REAL_DFT( 32f, float )
15686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_CCS_IDFT( 32f, float )
15696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void
15726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvCopyColumn( const uchar* _src, int src_step,
15736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn               uchar* _dst, int dst_step,
15746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn               int len, int elem_size )
15756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
15766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i, t0, t1;
15776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const int* src = (const int*)_src;
15786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int* dst = (int*)_dst;
15796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    src_step /= sizeof(src[0]);
15806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dst_step /= sizeof(dst[0]);
15816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( elem_size == sizeof(int) )
15836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
15846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < len; i++, src += src_step, dst += dst_step )
15856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[0] = src[0];
15866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
15876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else if( elem_size == sizeof(int)*2 )
15886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
15896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < len; i++, src += src_step, dst += dst_step )
15906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
15916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            t0 = src[0]; t1 = src[1];
15926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[0] = t0; dst[1] = t1;
15936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
15946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
15956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else if( elem_size == sizeof(int)*4 )
15966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
15976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < len; i++, src += src_step, dst += dst_step )
15986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
15996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            t0 = src[0]; t1 = src[1];
16006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[0] = t0; dst[1] = t1;
16016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            t0 = src[2]; t1 = src[3];
16026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[2] = t0; dst[3] = t1;
16036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
16046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
16056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
16066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void
16096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvCopyFrom2Columns( const uchar* _src, int src_step,
16106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                     uchar* _dst0, uchar* _dst1,
16116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                     int len, int elem_size )
16126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
16136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i, t0, t1;
16146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const int* src = (const int*)_src;
16156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int* dst0 = (int*)_dst0;
16166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int* dst1 = (int*)_dst1;
16176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    src_step /= sizeof(src[0]);
16186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( elem_size == sizeof(int) )
16206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
16216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < len; i++, src += src_step )
16226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
16236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            t0 = src[0]; t1 = src[1];
16246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst0[i] = t0; dst1[i] = t1;
16256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
16266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
16276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else if( elem_size == sizeof(int)*2 )
16286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
16296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < len*2; i += 2, src += src_step )
16306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
16316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            t0 = src[0]; t1 = src[1];
16326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst0[i] = t0; dst0[i+1] = t1;
16336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            t0 = src[2]; t1 = src[3];
16346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst1[i] = t0; dst1[i+1] = t1;
16356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
16366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
16376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else if( elem_size == sizeof(int)*4 )
16386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
16396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < len*4; i += 4, src += src_step )
16406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
16416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            t0 = src[0]; t1 = src[1];
16426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst0[i] = t0; dst0[i+1] = t1;
16436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            t0 = src[2]; t1 = src[3];
16446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst0[i+2] = t0; dst0[i+3] = t1;
16456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            t0 = src[4]; t1 = src[5];
16466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst1[i] = t0; dst1[i+1] = t1;
16476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            t0 = src[6]; t1 = src[7];
16486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst1[i+2] = t0; dst1[i+3] = t1;
16496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
16506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
16516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
16526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void
16556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvCopyTo2Columns( const uchar* _src0, const uchar* _src1,
16566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   uchar* _dst, int dst_step,
16576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   int len, int elem_size )
16586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
16596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i, t0, t1;
16606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const int* src0 = (const int*)_src0;
16616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const int* src1 = (const int*)_src1;
16626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int* dst = (int*)_dst;
16636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dst_step /= sizeof(dst[0]);
16646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( elem_size == sizeof(int) )
16666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
16676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < len; i++, dst += dst_step )
16686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
16696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            t0 = src0[i]; t1 = src1[i];
16706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[0] = t0; dst[1] = t1;
16716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
16726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
16736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else if( elem_size == sizeof(int)*2 )
16746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
16756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < len*2; i += 2, dst += dst_step )
16766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
16776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            t0 = src0[i]; t1 = src0[i+1];
16786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[0] = t0; dst[1] = t1;
16796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            t0 = src1[i]; t1 = src1[i+1];
16806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[2] = t0; dst[3] = t1;
16816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
16826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
16836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else if( elem_size == sizeof(int)*4 )
16846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
16856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < len*4; i += 4, dst += dst_step )
16866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
16876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            t0 = src0[i]; t1 = src0[i+1];
16886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[0] = t0; dst[1] = t1;
16896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            t0 = src0[i+2]; t1 = src0[i+3];
16906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[2] = t0; dst[3] = t1;
16916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            t0 = src1[i]; t1 = src1[i+1];
16926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[4] = t0; dst[5] = t1;
16936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            t0 = src1[i+2]; t1 = src1[i+3];
16946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dst[6] = t0; dst[7] = t1;
16956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
16966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
16976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
16986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void
17016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvExpandCCS( uchar* _ptr, int len, int elem_size )
17026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
17036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i;
17046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    _ptr -= elem_size;
17056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    memcpy( _ptr, _ptr + elem_size, elem_size );
17066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    memset( _ptr + elem_size, 0, elem_size );
17076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( (len & 1) == 0 )
17086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        memset( _ptr + (len+1)*elem_size, 0, elem_size );
17096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( elem_size == sizeof(float) )
17116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
17126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvComplex32f* ptr = (CvComplex32f*)_ptr;
17136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 1; i < (len+1)/2; i++ )
17156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
17166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CvComplex32f t;
17176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            t.re = ptr[i].re;
17186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            t.im = -ptr[i].im;
17196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ptr[len-i] = t;
17206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
17216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
17226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
17236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
17246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvComplex64f* ptr = (CvComplex64f*)_ptr;
17256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 1; i < (len+1)/2; i++ )
17276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
17286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CvComplex64f t;
17296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            t.re = ptr[i].re;
17306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            t.im = -ptr[i].im;
17316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ptr[len-i] = t;
17326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
17336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
17346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
17356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef CvStatus (CV_STDCALL *CvDFTFunc)(
17386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn     const void* src, void* dst, int n, int nf, int* factors,
17396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn     const int* itab, const void* wave, int tab_size,
17406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn     const void* spec, void* buf, int inv, double scale );
17416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void
17436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvDFT( const CvArr* srcarr, CvArr* dstarr, int flags, int nonzero_rows )
17446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
17456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    static CvDFTFunc dft_tbl[6];
17466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    static int inittab = 0;
17476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    void* buffer = 0;
17496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int local_alloc = 1;
17506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int depth = -1;
17516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    void *spec_c = 0, *spec_r = 0, *spec = 0;
17526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvDFT" );
17546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
17566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int prev_len = 0, buf_size = 0, stage = 0;
17586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int nf = 0, inv = (flags & CV_DXT_INVERSE) != 0;
17596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int real_transform = 0;
17606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat *src = (CvMat*)srcarr, *dst = (CvMat*)dstarr;
17616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat srcstub, dststub, *src0;
17626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int complex_elem_size, elem_size;
17636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int factors[34], inplace_transform = 0;
17646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int ipp_norm_flag = 0;
17656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !inittab )
17676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
17686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dft_tbl[0] = (CvDFTFunc)icvDFT_32fc;
17696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dft_tbl[1] = (CvDFTFunc)icvRealDFT_32f;
17706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dft_tbl[2] = (CvDFTFunc)icvCCSIDFT_32f;
17716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dft_tbl[3] = (CvDFTFunc)icvDFT_64fc;
17726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dft_tbl[4] = (CvDFTFunc)icvRealDFT_64f;
17736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dft_tbl[5] = (CvDFTFunc)icvCCSIDFT_64f;
17746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        inittab = 1;
17756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
17766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !CV_IS_MAT( src ))
17786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
17796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int coi = 0;
17806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( src = cvGetMat( src, &srcstub, &coi ));
17816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( coi != 0 )
17836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ERROR( CV_BadCOI, "" );
17846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
17856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !CV_IS_MAT( dst ))
17876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
17886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int coi = 0;
17896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( dst = cvGetMat( dst, &dststub, &coi ));
17906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( coi != 0 )
17926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ERROR( CV_BadCOI, "" );
17936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
17946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    src0 = src;
17966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    elem_size = CV_ELEM_SIZE1(src->type);
17976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    complex_elem_size = elem_size*2;
17986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // check types and sizes
18006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !CV_ARE_DEPTHS_EQ(src, dst) )
18016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsUnmatchedFormats, "" );
18026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    depth = CV_MAT_DEPTH(src->type);
18046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( depth < CV_32F )
18056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsUnsupportedFormat,
18066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        "Only 32fC1, 32fC2, 64fC1 and 64fC2 formats are supported" );
18076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( CV_ARE_CNS_EQ(src, dst) )
18096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
18106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( CV_MAT_CN(src->type) > 2 )
18116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ERROR( CV_StsUnsupportedFormat,
18126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            "Only 32fC1, 32fC2, 64fC1 and 64fC2 formats are supported" );
18136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( !CV_ARE_SIZES_EQ(src, dst) )
18156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ERROR( CV_StsUnmatchedSizes, "" );
18166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        real_transform = CV_MAT_CN(src->type) == 1;
18176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( !real_transform )
18186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            elem_size = complex_elem_size;
18196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
18206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else if( !inv && CV_MAT_CN(src->type) == 1 && CV_MAT_CN(dst->type) == 2 )
18216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
18226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( (src->cols != 1 || dst->cols != 1 ||
18236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            (src->rows/2+1 != dst->rows && src->rows != dst->rows)) &&
18246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            (src->cols/2+1 != dst->cols || src->rows != dst->rows) )
18256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ERROR( CV_StsUnmatchedSizes, "" );
18266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        real_transform = 1;
18276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
18286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else if( inv && CV_MAT_CN(src->type) == 2 && CV_MAT_CN(dst->type) == 1 )
18296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
18306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( (src->cols != 1 || dst->cols != 1 ||
18316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            (dst->rows/2+1 != src->rows && src->rows != dst->rows)) &&
18326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            (dst->cols/2+1 != src->cols || src->rows != dst->rows) )
18336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ERROR( CV_StsUnmatchedSizes, "" );
18346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        real_transform = 1;
18356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
18366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
18376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsUnmatchedFormats,
18386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        "Incorrect or unsupported combination of input & output formats" );
18396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( src->cols == 1 && nonzero_rows > 0 )
18416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsNotImplemented,
18426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        "This mode (using nonzero_rows with a single-column matrix) breaks the function logic, so it is prohibited.\n"
18436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        "For fast convolution/correlation use 2-column matrix or single-row matrix instead" );
18446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // determine, which transform to do first - row-wise
18466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // (stage 0) or column-wise (stage 1) transform
18476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !(flags & CV_DXT_ROWS) && src->rows > 1 &&
18486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        ((src->cols == 1 && !CV_IS_MAT_CONT(src->type & dst->type)) ||
18496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        (src->cols > 1 && inv && real_transform)) )
18506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        stage = 1;
18516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    ipp_norm_flag = !(flags & CV_DXT_SCALE) ? 8 : (flags & CV_DXT_INVERSE) ? 2 : 1;
18536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for(;;)
18556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
18566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        double scale = 1;
18576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        uchar* wave = 0;
18586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int* itab = 0;
18596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        uchar* ptr;
18606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int i, len, count, sz = 0;
18616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int use_buf = 0, odd_real = 0;
18626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvDFTFunc dft_func;
18636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( stage == 0 ) // row-wise transform
18656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
18666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            len = !inv ? src->cols : dst->cols;
18676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            count = src->rows;
18686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( len == 1 && !(flags & CV_DXT_ROWS) )
18696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
18706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                len = !inv ? src->rows : dst->rows;
18716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                count = 1;
18726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
18736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            odd_real = real_transform && (len & 1);
18746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
18756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
18766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
18776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            len = dst->rows;
18786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            count = !inv ? src0->cols : dst->cols;
18796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            sz = 2*len*complex_elem_size;
18806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
18816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        spec = 0;
18836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( len*count >= 64 && icvDFTInitAlloc_R_32f_p != 0 ) // use IPP DFT if available
18846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
18856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int ipp_sz = 0;
18866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( real_transform && stage == 0 )
18886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
18896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( depth == CV_32F )
18906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
18916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( spec_r )
18926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        IPPI_CALL( icvDFTFree_R_32f_p( spec_r ));
18936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    IPPI_CALL( icvDFTInitAlloc_R_32f_p(
18946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        &spec_r, len, ipp_norm_flag, cvAlgHintNone ));
18956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    IPPI_CALL( icvDFTGetBufSize_R_32f_p( spec_r, &ipp_sz ));
18966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
18976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else
18986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
18996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( spec_r )
19006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        IPPI_CALL( icvDFTFree_R_64f_p( spec_r ));
19016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    IPPI_CALL( icvDFTInitAlloc_R_64f_p(
19026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        &spec_r, len, ipp_norm_flag, cvAlgHintNone ));
19036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    IPPI_CALL( icvDFTGetBufSize_R_64f_p( spec_r, &ipp_sz ));
19046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
19056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                spec = spec_r;
19066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
19076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else
19086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
19096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( depth == CV_32F )
19106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
19116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( spec_c )
19126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        IPPI_CALL( icvDFTFree_C_32fc_p( spec_c ));
19136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    IPPI_CALL( icvDFTInitAlloc_C_32fc_p(
19146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        &spec_c, len, ipp_norm_flag, cvAlgHintNone ));
19156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    IPPI_CALL( icvDFTGetBufSize_C_32fc_p( spec_c, &ipp_sz ));
19166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
19176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else
19186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
19196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( spec_c )
19206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        IPPI_CALL( icvDFTFree_C_64fc_p( spec_c ));
19216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    IPPI_CALL( icvDFTInitAlloc_C_64fc_p(
19226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        &spec_c, len, ipp_norm_flag, cvAlgHintNone ));
19236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    IPPI_CALL( icvDFTGetBufSize_C_64fc_p( spec_c, &ipp_sz ));
19246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
19256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                spec = spec_c;
19266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
19276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
19286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            sz += ipp_sz;
19296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
19306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
19316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
19326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( len != prev_len )
19336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                nf = icvDFTFactorize( len, factors );
19346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
19356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            inplace_transform = factors[0] == factors[nf-1];
19366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            sz += len*(complex_elem_size + sizeof(int));
19376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            i = nf > 1 && (factors[0] & 1) == 0;
19386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( (factors[i] & 1) != 0 && factors[i] > 5 )
19396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                sz += (factors[i]+1)*complex_elem_size;
19406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
19416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( (stage == 0 && ((src->data.ptr == dst->data.ptr && !inplace_transform) || odd_real)) ||
19426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                (stage == 1 && !inplace_transform) )
19436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
19446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                use_buf = 1;
19456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                sz += len*complex_elem_size;
19466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
19476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
19486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
19496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( sz > buf_size )
19506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
19516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            prev_len = 0; // because we release the buffer,
19526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                          // force recalculation of
19536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                          // twiddle factors and permutation table
19546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( !local_alloc && buffer )
19556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                cvFree( &buffer );
19566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( sz <= CV_MAX_LOCAL_DFT_SIZE )
19576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
19586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                buf_size = sz = CV_MAX_LOCAL_DFT_SIZE;
19596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                buffer = cvStackAlloc(sz + 32);
19606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                local_alloc = 1;
19616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
19626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else
19636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
19646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CV_CALL( buffer = cvAlloc(sz + 32) );
19656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                buf_size = sz;
19666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                local_alloc = 0;
19676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
19686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
19696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
19706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        ptr = (uchar*)buffer;
19716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( !spec )
19726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
19736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            wave = ptr;
19746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ptr += len*complex_elem_size;
19756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            itab = (int*)ptr;
19766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ptr = (uchar*)cvAlignPtr( ptr + len*sizeof(int), 16 );
19776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
19786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( len != prev_len || (!inplace_transform && inv && real_transform))
19796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                icvDFTInit( len, nf, factors, itab, complex_elem_size,
19806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            wave, stage == 0 && inv && real_transform );
19816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            // otherwise reuse the tables calculated on the previous stage
19826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
19836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
19846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( stage == 0 )
19856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
19866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            uchar* tmp_buf = 0;
19876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int dptr_offset = 0;
19886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int dst_full_len = len*elem_size;
19896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int _flags = inv + (CV_MAT_CN(src->type) != CV_MAT_CN(dst->type) ?
19906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                         ICV_DFT_COMPLEX_INPUT_OR_OUTPUT : 0);
19916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( use_buf )
19926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
19936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                tmp_buf = ptr;
19946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ptr += len*complex_elem_size;
19956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( odd_real && !inv && len > 1 &&
19966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    !(_flags & ICV_DFT_COMPLEX_INPUT_OR_OUTPUT))
19976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dptr_offset = elem_size;
19986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
19996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
20006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( !inv && (_flags & ICV_DFT_COMPLEX_INPUT_OR_OUTPUT) )
20016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                dst_full_len += (len & 1) ? elem_size : complex_elem_size;
20026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
20036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dft_func = dft_tbl[(!real_transform ? 0 : !inv ? 1 : 2) + (depth == CV_64F)*3];
20046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
20056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( count > 1 && !(flags & CV_DXT_ROWS) && (!inv || !real_transform) )
20066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                stage = 1;
20076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else if( flags & CV_DXT_SCALE )
20086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                scale = 1./(len * (flags & CV_DXT_ROWS ? 1 : count));
20096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
20106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( nonzero_rows <= 0 || nonzero_rows > count )
20116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                nonzero_rows = count;
20126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
20136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( i = 0; i < nonzero_rows; i++ )
20146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
20156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                uchar* sptr = src->data.ptr + i*src->step;
20166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                uchar* dptr0 = dst->data.ptr + i*dst->step;
20176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                uchar* dptr = dptr0;
20186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
20196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( tmp_buf )
20206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dptr = tmp_buf;
20216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
20226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                dft_func( sptr, dptr, len, nf, factors, itab, wave, len, spec, ptr, _flags, scale );
20236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( dptr != dptr0 )
20246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    memcpy( dptr0, dptr + dptr_offset, dst_full_len );
20256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
20266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
20276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( ; i < count; i++ )
20286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
20296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                uchar* dptr0 = dst->data.ptr + i*dst->step;
20306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                memset( dptr0, 0, dst_full_len );
20316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
20326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
20336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( stage != 1 )
20346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                break;
20356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            src = dst;
20366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
20376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
20386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
20396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int a = 0, b = count;
20406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            uchar *buf0, *buf1, *dbuf0, *dbuf1;
20416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            uchar* sptr0 = src->data.ptr;
20426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            uchar* dptr0 = dst->data.ptr;
20436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            buf0 = ptr;
20446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ptr += len*complex_elem_size;
20456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            buf1 = ptr;
20466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ptr += len*complex_elem_size;
20476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dbuf0 = buf0, dbuf1 = buf1;
20486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
20496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( use_buf )
20506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
20516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                dbuf1 = ptr;
20526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                dbuf0 = buf1;
20536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ptr += len*complex_elem_size;
20546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
20556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
20566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dft_func = dft_tbl[(depth == CV_64F)*3];
20576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
20586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( real_transform && inv && src->cols > 1 )
20596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                stage = 0;
20606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else if( flags & CV_DXT_SCALE )
20616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                scale = 1./(len * count);
20626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
20636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( real_transform )
20646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
20656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int even;
20666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                a = 1;
20676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                even = (count & 1) == 0;
20686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                b = (count+1)/2;
20696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( !inv )
20706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
20716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    memset( buf0, 0, len*complex_elem_size );
20726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    icvCopyColumn( sptr0, src->step, buf0, complex_elem_size, len, elem_size );
20736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    sptr0 += CV_MAT_CN(dst->type)*elem_size;
20746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( even )
20756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
20766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        memset( buf1, 0, len*complex_elem_size );
20776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        icvCopyColumn( sptr0 + (count-2)*elem_size, src->step,
20786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                       buf1, complex_elem_size, len, elem_size );
20796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
20806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
20816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else if( CV_MAT_CN(src->type) == 1 )
20826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
20836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    icvCopyColumn( sptr0, src->step, buf0 + elem_size, elem_size, len, elem_size );
20846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    icvExpandCCS( buf0 + elem_size, len, elem_size );
20856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( even )
20866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
20876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        icvCopyColumn( sptr0 + (count-1)*elem_size, src->step,
20886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                       buf1 + elem_size, elem_size, len, elem_size );
20896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        icvExpandCCS( buf1 + elem_size, len, elem_size );
20906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
20916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    sptr0 += elem_size;
20926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
20936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else
20946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
20956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    icvCopyColumn( sptr0, src->step, buf0, complex_elem_size, len, complex_elem_size );
20966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    //memcpy( buf0 + elem_size, buf0, elem_size );
20976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    //icvExpandCCS( buf0 + elem_size, len, elem_size );
20986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( even )
20996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
21006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        icvCopyColumn( sptr0 + b*complex_elem_size, src->step,
21016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                       buf1, complex_elem_size, len, complex_elem_size );
21026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        //memcpy( buf0 + elem_size, buf0, elem_size );
21036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        //icvExpandCCS( buf0 + elem_size, len, elem_size );
21046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
21056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    sptr0 += complex_elem_size;
21066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
21076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
21086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( even )
21096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    IPPI_CALL( dft_func( buf1, dbuf1, len, nf, factors, itab,
21106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                         wave, len, spec, ptr, inv, scale ));
21116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                IPPI_CALL( dft_func( buf0, dbuf0, len, nf, factors, itab,
21126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                     wave, len, spec, ptr, inv, scale ));
21136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
21146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( CV_MAT_CN(dst->type) == 1 )
21156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
21166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( !inv )
21176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
21186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        // copy the half of output vector to the first/last column.
21196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        // before doing that, defgragment the vector
21206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        memcpy( dbuf0 + elem_size, dbuf0, elem_size );
21216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        icvCopyColumn( dbuf0 + elem_size, elem_size, dptr0,
21226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                       dst->step, len, elem_size );
21236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        if( even )
21246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        {
21256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            memcpy( dbuf1 + elem_size, dbuf1, elem_size );
21266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            icvCopyColumn( dbuf1 + elem_size, elem_size,
21276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                           dptr0 + (count-1)*elem_size,
21286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                           dst->step, len, elem_size );
21296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        }
21306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        dptr0 += elem_size;
21316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
21326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    else
21336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
21346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        // copy the real part of the complex vector to the first/last column
21356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        icvCopyColumn( dbuf0, complex_elem_size, dptr0, dst->step, len, elem_size );
21366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        if( even )
21376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            icvCopyColumn( dbuf1, complex_elem_size, dptr0 + (count-1)*elem_size,
21386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                           dst->step, len, elem_size );
21396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        dptr0 += elem_size;
21406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
21416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
21426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else
21436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
21446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    assert( !inv );
21456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    icvCopyColumn( dbuf0, complex_elem_size, dptr0,
21466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                   dst->step, len, complex_elem_size );
21476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( even )
21486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        icvCopyColumn( dbuf1, complex_elem_size,
21496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                       dptr0 + b*complex_elem_size,
21506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                       dst->step, len, complex_elem_size );
21516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dptr0 += complex_elem_size;
21526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
21536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
21546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
21556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( i = a; i < b; i += 2 )
21566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
21576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( i+1 < b )
21586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
21596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    icvCopyFrom2Columns( sptr0, src->step, buf0, buf1, len, complex_elem_size );
21606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    IPPI_CALL( dft_func( buf1, dbuf1, len, nf, factors, itab,
21616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                         wave, len, spec, ptr, inv, scale ));
21626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
21636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else
21646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    icvCopyColumn( sptr0, src->step, buf0, complex_elem_size, len, complex_elem_size );
21656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
21666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                IPPI_CALL( dft_func( buf0, dbuf0, len, nf, factors, itab,
21676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                     wave, len, spec, ptr, inv, scale ));
21686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
21696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( i+1 < b )
21706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    icvCopyTo2Columns( dbuf0, dbuf1, dptr0, dst->step, len, complex_elem_size );
21716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else
21726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    icvCopyColumn( dbuf0, complex_elem_size, dptr0, dst->step, len, complex_elem_size );
21736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                sptr0 += 2*complex_elem_size;
21746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                dptr0 += 2*complex_elem_size;
21756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
21766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
21776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( stage != 0 )
21786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                break;
21796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            src = dst;
21806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
21816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
21826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
21836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
21846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
21856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( buffer && !local_alloc )
21866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvFree( &buffer );
21876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
21886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( spec_c )
21896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
21906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( depth == CV_32F )
21916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            icvDFTFree_C_32fc_p( spec_c );
21926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
21936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            icvDFTFree_C_64fc_p( spec_c );
21946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
21956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
21966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( spec_r )
21976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
21986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( depth == CV_32F )
21996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            icvDFTFree_R_32f_p( spec_r );
22006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
22016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            icvDFTFree_R_64f_p( spec_r );
22026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
22036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
22046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
22056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
22066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void
22076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvMulSpectrums( const CvArr* srcAarr, const CvArr* srcBarr,
22086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CvArr* dstarr, int flags )
22096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
22106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvMulSpectrums" );
22116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
22126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
22136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
22146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat stubA, *srcA = (CvMat*)srcAarr;
22156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat stubB, *srcB = (CvMat*)srcBarr;
22166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat dststub, *dst = (CvMat*)dstarr;
22176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int stepA, stepB, stepC;
22186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int type, cn, is_1d;
22196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int j, j0, j1, k, rows, cols, ncols;
22206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
22216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !CV_IS_MAT(srcA))
22226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( srcA = cvGetMat( srcA, &stubA, 0 ));
22236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
22246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !CV_IS_MAT(srcB))
22256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( srcB = cvGetMat( srcB, &stubB, 0 ));
22266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
22276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !CV_IS_MAT(dst))
22286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( dst = cvGetMat( dst, &dststub, 0 ));
22296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
22306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !CV_ARE_TYPES_EQ( srcA, srcB ) || !CV_ARE_TYPES_EQ( srcA, dst ))
22316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsUnmatchedFormats, "" );
22326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
22336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !CV_ARE_SIZES_EQ( srcA, srcB ) || !CV_ARE_SIZES_EQ( srcA, dst ))
22346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsUnmatchedSizes, "" );
22356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
22366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    type = CV_MAT_TYPE( dst->type );
22376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cn = CV_MAT_CN(type);
22386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    rows = srcA->rows;
22396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cols = srcA->cols;
22406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    is_1d = (flags & CV_DXT_ROWS) ||
22416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            (rows == 1 || (cols == 1 &&
22426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn             CV_IS_MAT_CONT( srcA->type & srcB->type & dst->type )));
22436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
22446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( is_1d && !(flags & CV_DXT_ROWS) )
22456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cols = cols + rows - 1, rows = 1;
22466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    ncols = cols*cn;
22476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    j0 = cn == 1;
22486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    j1 = ncols - (cols % 2 == 0 && cn == 1);
22496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
22506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( CV_MAT_DEPTH(type) == CV_32F )
22516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
22526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        float* dataA = srcA->data.fl;
22536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        float* dataB = srcB->data.fl;
22546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        float* dataC = dst->data.fl;
22556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
22566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        stepA = srcA->step/sizeof(dataA[0]);
22576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        stepB = srcB->step/sizeof(dataB[0]);
22586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        stepC = dst->step/sizeof(dataC[0]);
22596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
22606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( !is_1d && cn == 1 )
22616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
22626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( k = 0; k < (cols % 2 ? 1 : 2); k++ )
22636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
22646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( k == 1 )
22656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dataA += cols - 1, dataB += cols - 1, dataC += cols - 1;
22666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                dataC[0] = dataA[0]*dataB[0];
22676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( rows % 2 == 0 )
22686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dataC[(rows-1)*stepC] = dataA[(rows-1)*stepA]*dataB[(rows-1)*stepB];
22696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( !(flags & CV_DXT_MUL_CONJ) )
22706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( j = 1; j <= rows - 2; j += 2 )
22716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
22726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        double re = (double)dataA[j*stepA]*dataB[j*stepB] -
22736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                    (double)dataA[(j+1)*stepA]*dataB[(j+1)*stepB];
22746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        double im = (double)dataA[j*stepA]*dataB[(j+1)*stepB] +
22756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                    (double)dataA[(j+1)*stepA]*dataB[j*stepB];
22766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        dataC[j*stepC] = (float)re; dataC[(j+1)*stepC] = (float)im;
22776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
22786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else
22796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( j = 1; j <= rows - 2; j += 2 )
22806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
22816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        double re = (double)dataA[j*stepA]*dataB[j*stepB] +
22826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                    (double)dataA[(j+1)*stepA]*dataB[(j+1)*stepB];
22836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        double im = (double)dataA[(j+1)*stepA]*dataB[j*stepB] -
22846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                    (double)dataA[j*stepA]*dataB[(j+1)*stepB];
22856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        dataC[j*stepC] = (float)re; dataC[(j+1)*stepC] = (float)im;
22866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
22876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( k == 1 )
22886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dataA -= cols - 1, dataB -= cols - 1, dataC -= cols - 1;
22896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
22906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
22916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
22926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( ; rows--; dataA += stepA, dataB += stepB, dataC += stepC )
22936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
22946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( is_1d && cn == 1 )
22956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
22966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                dataC[0] = dataA[0]*dataB[0];
22976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( cols % 2 == 0 )
22986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dataC[j1] = dataA[j1]*dataB[j1];
22996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
23006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
23016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( !(flags & CV_DXT_MUL_CONJ) )
23026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( j = j0; j < j1; j += 2 )
23036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
23046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    double re = (double)dataA[j]*dataB[j] - (double)dataA[j+1]*dataB[j+1];
23056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    double im = (double)dataA[j+1]*dataB[j] + (double)dataA[j]*dataB[j+1];
23066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dataC[j] = (float)re; dataC[j+1] = (float)im;
23076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
23086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else
23096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( j = j0; j < j1; j += 2 )
23106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
23116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    double re = (double)dataA[j]*dataB[j] + (double)dataA[j+1]*dataB[j+1];
23126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    double im = (double)dataA[j+1]*dataB[j] - (double)dataA[j]*dataB[j+1];
23136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dataC[j] = (float)re; dataC[j+1] = (float)im;
23146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
23156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
23166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
23176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else if( CV_MAT_DEPTH(type) == CV_64F )
23186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
23196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        double* dataA = srcA->data.db;
23206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        double* dataB = srcB->data.db;
23216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        double* dataC = dst->data.db;
23226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
23236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        stepA = srcA->step/sizeof(dataA[0]);
23246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        stepB = srcB->step/sizeof(dataB[0]);
23256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        stepC = dst->step/sizeof(dataC[0]);
23266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
23276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( !is_1d && cn == 1 )
23286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
23296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( k = 0; k < (cols % 2 ? 1 : 2); k++ )
23306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
23316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( k == 1 )
23326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dataA += cols - 1, dataB += cols - 1, dataC += cols - 1;
23336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                dataC[0] = dataA[0]*dataB[0];
23346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( rows % 2 == 0 )
23356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dataC[(rows-1)*stepC] = dataA[(rows-1)*stepA]*dataB[(rows-1)*stepB];
23366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( !(flags & CV_DXT_MUL_CONJ) )
23376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( j = 1; j <= rows - 2; j += 2 )
23386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
23396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        double re = dataA[j*stepA]*dataB[j*stepB] -
23406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                    dataA[(j+1)*stepA]*dataB[(j+1)*stepB];
23416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        double im = dataA[j*stepA]*dataB[(j+1)*stepB] +
23426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                    dataA[(j+1)*stepA]*dataB[j*stepB];
23436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        dataC[j*stepC] = re; dataC[(j+1)*stepC] = im;
23446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
23456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else
23466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( j = 1; j <= rows - 2; j += 2 )
23476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
23486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        double re = dataA[j*stepA]*dataB[j*stepB] +
23496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                    dataA[(j+1)*stepA]*dataB[(j+1)*stepB];
23506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        double im = dataA[(j+1)*stepA]*dataB[j*stepB] -
23516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                    dataA[j*stepA]*dataB[(j+1)*stepB];
23526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        dataC[j*stepC] = re; dataC[(j+1)*stepC] = im;
23536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
23546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( k == 1 )
23556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dataA -= cols - 1, dataB -= cols - 1, dataC -= cols - 1;
23566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
23576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
23586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
23596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( ; rows--; dataA += stepA, dataB += stepB, dataC += stepC )
23606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
23616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( is_1d && cn == 1 )
23626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
23636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                dataC[0] = dataA[0]*dataB[0];
23646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( cols % 2 == 0 )
23656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dataC[j1] = dataA[j1]*dataB[j1];
23666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
23676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
23686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( !(flags & CV_DXT_MUL_CONJ) )
23696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( j = j0; j < j1; j += 2 )
23706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
23716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    double re = dataA[j]*dataB[j] - dataA[j+1]*dataB[j+1];
23726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    double im = dataA[j+1]*dataB[j] + dataA[j]*dataB[j+1];
23736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dataC[j] = re; dataC[j+1] = im;
23746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
23756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else
23766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( j = j0; j < j1; j += 2 )
23776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
23786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    double re = dataA[j]*dataB[j] + dataA[j+1]*dataB[j+1];
23796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    double im = dataA[j+1]*dataB[j] - dataA[j]*dataB[j+1];
23806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    dataC[j] = re; dataC[j+1] = im;
23816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
23826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
23836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
23846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
23856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
23866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsUnsupportedFormat, "Only 32f and 64f types are supported" );
23876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
23886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
23896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
23906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
23916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
23926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
23936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/****************************************************************************************\
23946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                               Discrete Cosine Transform
23956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn\****************************************************************************************/
23966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
23976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* DCT is calculated using DFT, as described here:
23986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn   http://www.ece.utexas.edu/~bevans/courses/ee381k/lectures/09_DCT/lecture9/:
23996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn*/
24006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define ICV_DCT_FWD( flavor, datatype )                                 \
24016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvStatus CV_STDCALL                                              \
24026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvDCT_fwd_##flavor( const datatype* src, int src_step, datatype* dft_src,\
24036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                     datatype* dft_dst, datatype* dst, int dst_step,    \
24046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                     int n, int nf, int* factors, const int* itab,      \
24056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                     const CvComplex##flavor* dft_wave,                 \
24066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                     const CvComplex##flavor* dct_wave,                 \
24076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                     const void* spec, CvComplex##flavor* buf )         \
24086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{                                                                       \
24096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int j, n2 = n >> 1;                                                 \
24106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                        \
24116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    src_step /= sizeof(src[0]);                                         \
24126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dst_step /= sizeof(dst[0]);                                         \
24136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    datatype* dst1 = dst + (n-1)*dst_step;                              \
24146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                        \
24156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( n == 1 )                                                        \
24166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {                                                                   \
24176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dst[0] = src[0];                                                \
24186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_OK;                                                   \
24196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }                                                                   \
24206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                        \
24216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( j = 0; j < n2; j++, src += src_step*2 )                        \
24226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {                                                                   \
24236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dft_src[j] = src[0];                                            \
24246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dft_src[n-j-1] = src[src_step];                                 \
24256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }                                                                   \
24266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                        \
24276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    icvRealDFT_##flavor( dft_src, dft_dst, n, nf, factors,              \
24286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                         itab, dft_wave, n, spec, buf, 0, 1.0 );        \
24296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    src = dft_dst;                                                      \
24306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                        \
24316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dst[0] = (datatype)(src[0]*dct_wave->re*icv_sin_45);                \
24326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dst += dst_step;                                                    \
24336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( j = 1, dct_wave++; j < n2; j++, dct_wave++,                    \
24346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                    dst += dst_step, dst1 -= dst_step ) \
24356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {                                                                   \
24366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        double t0 = dct_wave->re*src[j*2-1] - dct_wave->im*src[j*2];    \
24376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        double t1 = -dct_wave->im*src[j*2-1] - dct_wave->re*src[j*2];   \
24386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dst[0] = (datatype)t0;                                          \
24396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dst1[0] = (datatype)t1;                                         \
24406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }                                                                   \
24416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                        \
24426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dst[0] = (datatype)(src[n-1]*dct_wave->re);                         \
24436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return CV_OK;                                                       \
24446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
24456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
24466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
24476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#define ICV_DCT_INV( flavor, datatype )                                 \
24486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvStatus CV_STDCALL                                              \
24496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvDCT_inv_##flavor( const datatype* src, int src_step, datatype* dft_src,\
24506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                     datatype* dft_dst, datatype* dst, int dst_step,    \
24516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                     int n, int nf, int* factors, const int* itab,      \
24526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                     const CvComplex##flavor* dft_wave,                 \
24536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                     const CvComplex##flavor* dct_wave,                 \
24546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                     const void* spec, CvComplex##flavor* buf )         \
24556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{                                                                       \
24566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int j, n2 = n >> 1;                                                 \
24576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                        \
24586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    src_step /= sizeof(src[0]);                                         \
24596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dst_step /= sizeof(dst[0]);                                         \
24606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    const datatype* src1 = src + (n-1)*src_step;                        \
24616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                        \
24626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( n == 1 )                                                        \
24636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {                                                                   \
24646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dst[0] = src[0];                                                \
24656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_OK;                                                   \
24666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }                                                                   \
24676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                        \
24686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dft_src[0] = (datatype)(src[0]*2*dct_wave->re*icv_sin_45);          \
24696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    src += src_step;                                                    \
24706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( j = 1, dct_wave++; j < n2; j++, dct_wave++,                    \
24716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                    src += src_step, src1 -= src_step ) \
24726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {                                                                   \
24736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        double t0 = dct_wave->re*src[0] - dct_wave->im*src1[0];         \
24746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        double t1 = -dct_wave->im*src[0] - dct_wave->re*src1[0];        \
24756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dft_src[j*2-1] = (datatype)t0;                                  \
24766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dft_src[j*2] = (datatype)t1;                                    \
24776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }                                                                   \
24786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                        \
24796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dft_src[n-1] = (datatype)(src[0]*2*dct_wave->re);                   \
24806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    icvCCSIDFT_##flavor( dft_src, dft_dst, n, nf, factors, itab,        \
24816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                         dft_wave, n, spec, buf, CV_DXT_INVERSE, 1.0 ); \
24826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                                        \
24836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( j = 0; j < n2; j++, dst += dst_step*2 )                        \
24846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {                                                                   \
24856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dst[0] = dft_dst[j];                                            \
24866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dst[dst_step] = dft_dst[n-j-1];                                 \
24876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }                                                                   \
24886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return CV_OK;                                                       \
24896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
24906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
24916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
24926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_DCT_FWD( 64f, double )
24936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_DCT_INV( 64f, double )
24946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_DCT_FWD( 32f, float )
24956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennICV_DCT_INV( 32f, float )
24966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
24976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic void
24986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvDCTInit( int n, int elem_size, void* _wave, int inv )
24996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
25006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    static const double icvDctScale[] =
25016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
25026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.707106781186547570, 0.500000000000000000, 0.353553390593273790,
25036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.250000000000000000, 0.176776695296636890, 0.125000000000000000,
25046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.088388347648318447, 0.062500000000000000, 0.044194173824159223,
25056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.031250000000000000, 0.022097086912079612, 0.015625000000000000,
25066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.011048543456039806, 0.007812500000000000, 0.005524271728019903,
25076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.003906250000000000, 0.002762135864009952, 0.001953125000000000,
25086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.001381067932004976, 0.000976562500000000, 0.000690533966002488,
25096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.000488281250000000, 0.000345266983001244, 0.000244140625000000,
25106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.000172633491500622, 0.000122070312500000, 0.000086316745750311,
25116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    0.000061035156250000, 0.000043158372875155, 0.000030517578125000
25126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    };
25136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
25146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i;
25156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvComplex64f w, w1;
25166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    double t, scale;
25176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
25186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( n == 1 )
25196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return;
25206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
25216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    assert( (n&1) == 0 );
25226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
25236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( (n & (n - 1)) == 0 )
25246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
25256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int m = icvlog2(n);
25266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        scale = (!inv ? 2 : 1)*icvDctScale[m];
25276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        w1.re = icvDxtTab[m+2][0];
25286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        w1.im = -icvDxtTab[m+2][1];
25296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
25306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
25316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
25326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        t = 1./(2*n);
25336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        scale = (!inv ? 2 : 1)*sqrt(t);
25346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        w1.im = sin(-CV_PI*t);
25356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        w1.re = sqrt(1. - w1.im*w1.im);
25366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
25376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    n >>= 1;
25386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
25396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( elem_size == sizeof(CvComplex64f) )
25406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
25416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvComplex64f* wave = (CvComplex64f*)_wave;
25426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
25436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        w.re = scale;
25446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        w.im = 0.;
25456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
25466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i <= n; i++ )
25476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
25486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            wave[i] = w;
25496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            t = w.re*w1.re - w.im*w1.im;
25506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            w.im = w.re*w1.im + w.im*w1.re;
25516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            w.re = t;
25526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
25536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
25546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
25556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
25566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvComplex32f* wave = (CvComplex32f*)_wave;
25576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        assert( elem_size == sizeof(CvComplex32f) );
25586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
25596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        w.re = (float)scale;
25606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        w.im = 0.f;
25616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
25626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i <= n; i++ )
25636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
25646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            wave[i].re = (float)w.re;
25656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            wave[i].im = (float)w.im;
25666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            t = w.re*w1.re - w.im*w1.im;
25676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            w.im = w.re*w1.im + w.im*w1.re;
25686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            w.re = t;
25696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
25706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
25716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
25726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
25736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
25746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renntypedef CvStatus (CV_STDCALL * CvDCTFunc)(
25756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                const void* src, int src_step, void* dft_src,
25766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                void* dft_dst, void* dst, int dst_step, int n,
25776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int nf, int* factors, const int* itab, const void* dft_wave,
25786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                const void* dct_wave, const void* spec, void* buf );
25796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
25806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void
25816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvDCT( const CvArr* srcarr, CvArr* dstarr, int flags )
25826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
25836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    static CvDCTFunc dct_tbl[4];
25846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    static int inittab = 0;
25856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
25866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    void* buffer = 0;
25876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int local_alloc = 1;
25886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int inv = (flags & CV_DXT_INVERSE) != 0, depth = -1;
25896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    void *spec_dft = 0, *spec = 0;
25906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
25916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvDCT" );
25926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
25936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
25946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
25956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    double scale = 1.;
25966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int prev_len = 0, buf_size = 0, nf = 0, stage, end_stage;
25976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat *src = (CvMat*)srcarr, *dst = (CvMat*)dstarr;
25986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    uchar *src_dft_buf = 0, *dst_dft_buf = 0;
25996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    uchar *dft_wave = 0, *dct_wave = 0;
26006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int* itab = 0;
26016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    uchar* ptr = 0;
26026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvMat srcstub, dststub;
26036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int complex_elem_size, elem_size;
26046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int factors[34], inplace_transform;
26056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i, len, count;
26066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvDCTFunc dct_func;
26076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
26086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !inittab )
26096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
26106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dct_tbl[0] = (CvDCTFunc)icvDCT_fwd_32f;
26116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dct_tbl[1] = (CvDCTFunc)icvDCT_inv_32f;
26126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dct_tbl[2] = (CvDCTFunc)icvDCT_fwd_64f;
26136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        dct_tbl[3] = (CvDCTFunc)icvDCT_inv_64f;
26146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        inittab = 1;
26156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
26166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
26176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !CV_IS_MAT( src ))
26186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
26196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int coi = 0;
26206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( src = cvGetMat( src, &srcstub, &coi ));
26216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
26226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( coi != 0 )
26236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ERROR( CV_BadCOI, "" );
26246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
26256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
26266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !CV_IS_MAT( dst ))
26276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
26286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int coi = 0;
26296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( dst = cvGetMat( dst, &dststub, &coi ));
26306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
26316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( coi != 0 )
26326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ERROR( CV_BadCOI, "" );
26336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
26346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
26356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    depth = CV_MAT_DEPTH(src->type);
26366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    elem_size = CV_ELEM_SIZE1(depth);
26376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    complex_elem_size = elem_size*2;
26386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
26396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    // check types and sizes
26406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !CV_ARE_TYPES_EQ(src, dst) )
26416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsUnmatchedFormats, "" );
26426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
26436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( depth < CV_32F || CV_MAT_CN(src->type) != 1 )
26446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsUnsupportedFormat,
26456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        "Only 32fC1 and 64fC1 formats are supported" );
26466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
26476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    dct_func = dct_tbl[inv + (depth == CV_64F)*2];
26486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
26496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( (flags & CV_DXT_ROWS) || src->rows == 1 ||
26506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        (src->cols == 1 && CV_IS_MAT_CONT(src->type & dst->type)))
26516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
26526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        stage = end_stage = 0;
26536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
26546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
26556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
26566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        stage = src->cols == 1;
26576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        end_stage = 1;
26586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
26596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
26606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( ; stage <= end_stage; stage++ )
26616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
26626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        uchar *sptr = src->data.ptr, *dptr = dst->data.ptr;
26636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int sstep0, sstep1, dstep0, dstep1;
26646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
26656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( stage == 0 )
26666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
26676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            len = src->cols;
26686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            count = src->rows;
26696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( len == 1 && !(flags & CV_DXT_ROWS) )
26706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
26716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                len = src->rows;
26726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                count = 1;
26736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
26746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            sstep0 = src->step;
26756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dstep0 = dst->step;
26766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            sstep1 = dstep1 = elem_size;
26776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
26786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
26796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
26806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            len = dst->rows;
26816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            count = dst->cols;
26826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            sstep1 = src->step;
26836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dstep1 = dst->step;
26846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            sstep0 = dstep0 = elem_size;
26856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
26866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
26876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( len != prev_len )
26886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
26896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int sz;
26906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
26916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( len > 1 && (len & 1) )
26926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CV_ERROR( CV_StsNotImplemented, "Odd-size DCT\'s are not implemented" );
26936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
26946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            sz = len*elem_size;
26956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            sz += (len/2 + 1)*complex_elem_size;
26966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
26976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            spec = 0;
26986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            inplace_transform = 1;
26996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( len*count >= 64 && icvDFTInitAlloc_R_32f_p )
27006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
27016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int ipp_sz = 0;
27026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( depth == CV_32F )
27036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
27046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( spec_dft )
27056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        IPPI_CALL( icvDFTFree_R_32f_p( spec_dft ));
27066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    IPPI_CALL( icvDFTInitAlloc_R_32f_p( &spec_dft, len, 8, cvAlgHintNone ));
27076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    IPPI_CALL( icvDFTGetBufSize_R_32f_p( spec_dft, &ipp_sz ));
27086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
27096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else
27106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
27116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( spec_dft )
27126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        IPPI_CALL( icvDFTFree_R_64f_p( spec_dft ));
27136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    IPPI_CALL( icvDFTInitAlloc_R_64f_p( &spec_dft, len, 8, cvAlgHintNone ));
27146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    IPPI_CALL( icvDFTGetBufSize_R_64f_p( spec_dft, &ipp_sz ));
27156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
27166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                spec = spec_dft;
27176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                sz += ipp_sz;
27186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
27196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            else
27206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
27216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                sz += len*(complex_elem_size + sizeof(int)) + complex_elem_size;
27226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
27236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                nf = icvDFTFactorize( len, factors );
27246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                inplace_transform = factors[0] == factors[nf-1];
27256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
27266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                i = nf > 1 && (factors[0] & 1) == 0;
27276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( (factors[i] & 1) != 0 && factors[i] > 5 )
27286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    sz += (factors[i]+1)*complex_elem_size;
27296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
27306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( !inplace_transform )
27316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    sz += len*elem_size;
27326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
27336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
27346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( sz > buf_size )
27356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
27366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( !local_alloc && buffer )
27376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    cvFree( &buffer );
27386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( sz <= CV_MAX_LOCAL_DFT_SIZE )
27396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
27406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    buf_size = sz = CV_MAX_LOCAL_DFT_SIZE;
27416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    buffer = cvStackAlloc(sz + 32);
27426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    local_alloc = 1;
27436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
27446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                else
27456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
27466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CV_CALL( buffer = cvAlloc(sz + 32) );
27476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    buf_size = sz;
27486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    local_alloc = 0;
27496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
27506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
27516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
27526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ptr = (uchar*)buffer;
27536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( !spec )
27546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
27556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                dft_wave = ptr;
27566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ptr += len*complex_elem_size;
27576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                itab = (int*)ptr;
27586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ptr = (uchar*)cvAlignPtr( ptr + len*sizeof(int), 16 );
27596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                icvDFTInit( len, nf, factors, itab, complex_elem_size, dft_wave, inv );
27606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
27616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
27626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dct_wave = ptr;
27636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ptr += (len/2 + 1)*complex_elem_size;
27646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            src_dft_buf = dst_dft_buf = ptr;
27656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ptr += len*elem_size;
27666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( !inplace_transform )
27676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
27686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                dst_dft_buf = ptr;
27696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ptr += len*elem_size;
27706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
27716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            icvDCTInit( len, complex_elem_size, dct_wave, inv );
27726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( !inv )
27736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                scale += scale;
27746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            prev_len = len;
27756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
27766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        // otherwise reuse the tables calculated on the previous stage
27776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
27786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < count; i++ )
27796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
27806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            dct_func( sptr + i*sstep0, sstep1, src_dft_buf, dst_dft_buf,
27816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                      dptr + i*dstep0, dstep1, len, nf, factors,
27826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                      itab, dft_wave, dct_wave, spec, ptr );
27836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
27846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        src = dst;
27856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
27866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
27876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
27886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
27896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( spec_dft )
27906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
27916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( depth == CV_32F )
27926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            icvDFTFree_R_32f_p( spec_dft );
27936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
27946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            icvDFTFree_R_64f_p( spec_dft );
27956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
27966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
27976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( buffer && !local_alloc )
27986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvFree( &buffer );
27996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
28006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
28016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
28026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic const int icvOptimalDFTSize[] = {
28036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24, 25, 27, 30, 32, 36, 40, 45, 48,
28046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn50, 54, 60, 64, 72, 75, 80, 81, 90, 96, 100, 108, 120, 125, 128, 135, 144, 150, 160,
28056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn162, 180, 192, 200, 216, 225, 240, 243, 250, 256, 270, 288, 300, 320, 324, 360, 375,
28066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn384, 400, 405, 432, 450, 480, 486, 500, 512, 540, 576, 600, 625, 640, 648, 675, 720,
28076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn729, 750, 768, 800, 810, 864, 900, 960, 972, 1000, 1024, 1080, 1125, 1152, 1200,
28086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn1215, 1250, 1280, 1296, 1350, 1440, 1458, 1500, 1536, 1600, 1620, 1728, 1800, 1875,
28096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn1920, 1944, 2000, 2025, 2048, 2160, 2187, 2250, 2304, 2400, 2430, 2500, 2560, 2592,
28106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn2700, 2880, 2916, 3000, 3072, 3125, 3200, 3240, 3375, 3456, 3600, 3645, 3750, 3840,
28116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn3888, 4000, 4050, 4096, 4320, 4374, 4500, 4608, 4800, 4860, 5000, 5120, 5184, 5400,
28126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn5625, 5760, 5832, 6000, 6075, 6144, 6250, 6400, 6480, 6561, 6750, 6912, 7200, 7290,
28136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn7500, 7680, 7776, 8000, 8100, 8192, 8640, 8748, 9000, 9216, 9375, 9600, 9720, 10000,
28146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn10125, 10240, 10368, 10800, 10935, 11250, 11520, 11664, 12000, 12150, 12288, 12500,
28156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn12800, 12960, 13122, 13500, 13824, 14400, 14580, 15000, 15360, 15552, 15625, 16000,
28166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn16200, 16384, 16875, 17280, 17496, 18000, 18225, 18432, 18750, 19200, 19440, 19683,
28176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn20000, 20250, 20480, 20736, 21600, 21870, 22500, 23040, 23328, 24000, 24300, 24576,
28186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn25000, 25600, 25920, 26244, 27000, 27648, 28125, 28800, 29160, 30000, 30375, 30720,
28196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn31104, 31250, 32000, 32400, 32768, 32805, 33750, 34560, 34992, 36000, 36450, 36864,
28206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn37500, 38400, 38880, 39366, 40000, 40500, 40960, 41472, 43200, 43740, 45000, 46080,
28216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn46656, 46875, 48000, 48600, 49152, 50000, 50625, 51200, 51840, 52488, 54000, 54675,
28226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn55296, 56250, 57600, 58320, 59049, 60000, 60750, 61440, 62208, 62500, 64000, 64800,
28236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn65536, 65610, 67500, 69120, 69984, 72000, 72900, 73728, 75000, 76800, 77760, 78125,
28246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn78732, 80000, 81000, 81920, 82944, 84375, 86400, 87480, 90000, 91125, 92160, 93312,
28256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn93750, 96000, 97200, 98304, 98415, 100000, 101250, 102400, 103680, 104976, 108000,
28266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn109350, 110592, 112500, 115200, 116640, 118098, 120000, 121500, 122880, 124416, 125000,
28276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn128000, 129600, 131072, 131220, 135000, 138240, 139968, 140625, 144000, 145800, 147456,
28286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn150000, 151875, 153600, 155520, 156250, 157464, 160000, 162000, 163840, 164025, 165888,
28296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn168750, 172800, 174960, 177147, 180000, 182250, 184320, 186624, 187500, 192000, 194400,
28306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn196608, 196830, 200000, 202500, 204800, 207360, 209952, 216000, 218700, 221184, 225000,
28316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn230400, 233280, 234375, 236196, 240000, 243000, 245760, 248832, 250000, 253125, 256000,
28326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn259200, 262144, 262440, 270000, 273375, 276480, 279936, 281250, 288000, 291600, 294912,
28336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn295245, 300000, 303750, 307200, 311040, 312500, 314928, 320000, 324000, 327680, 328050,
28346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn331776, 337500, 345600, 349920, 354294, 360000, 364500, 368640, 373248, 375000, 384000,
28356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn388800, 390625, 393216, 393660, 400000, 405000, 409600, 414720, 419904, 421875, 432000,
28366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn437400, 442368, 450000, 455625, 460800, 466560, 468750, 472392, 480000, 486000, 491520,
28376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn492075, 497664, 500000, 506250, 512000, 518400, 524288, 524880, 531441, 540000, 546750,
28386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn552960, 559872, 562500, 576000, 583200, 589824, 590490, 600000, 607500, 614400, 622080,
28396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn625000, 629856, 640000, 648000, 655360, 656100, 663552, 675000, 691200, 699840, 703125,
28406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn708588, 720000, 729000, 737280, 746496, 750000, 759375, 768000, 777600, 781250, 786432,
28416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn787320, 800000, 810000, 819200, 820125, 829440, 839808, 843750, 864000, 874800, 884736,
28426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn885735, 900000, 911250, 921600, 933120, 937500, 944784, 960000, 972000, 983040, 984150,
28436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn995328, 1000000, 1012500, 1024000, 1036800, 1048576, 1049760, 1062882, 1080000, 1093500,
28446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn1105920, 1119744, 1125000, 1152000, 1166400, 1171875, 1179648, 1180980, 1200000,
28456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn1215000, 1228800, 1244160, 1250000, 1259712, 1265625, 1280000, 1296000, 1310720,
28466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn1312200, 1327104, 1350000, 1366875, 1382400, 1399680, 1406250, 1417176, 1440000,
28476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn1458000, 1474560, 1476225, 1492992, 1500000, 1518750, 1536000, 1555200, 1562500,
28486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn1572864, 1574640, 1594323, 1600000, 1620000, 1638400, 1640250, 1658880, 1679616,
28496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn1687500, 1728000, 1749600, 1769472, 1771470, 1800000, 1822500, 1843200, 1866240,
28506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn1875000, 1889568, 1920000, 1944000, 1953125, 1966080, 1968300, 1990656, 2000000,
28516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn2025000, 2048000, 2073600, 2097152, 2099520, 2109375, 2125764, 2160000, 2187000,
28526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn2211840, 2239488, 2250000, 2278125, 2304000, 2332800, 2343750, 2359296, 2361960,
28536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn2400000, 2430000, 2457600, 2460375, 2488320, 2500000, 2519424, 2531250, 2560000,
28546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn2592000, 2621440, 2624400, 2654208, 2657205, 2700000, 2733750, 2764800, 2799360,
28556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn2812500, 2834352, 2880000, 2916000, 2949120, 2952450, 2985984, 3000000, 3037500,
28566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn3072000, 3110400, 3125000, 3145728, 3149280, 3188646, 3200000, 3240000, 3276800,
28576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn3280500, 3317760, 3359232, 3375000, 3456000, 3499200, 3515625, 3538944, 3542940,
28586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn3600000, 3645000, 3686400, 3732480, 3750000, 3779136, 3796875, 3840000, 3888000,
28596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn3906250, 3932160, 3936600, 3981312, 4000000, 4050000, 4096000, 4100625, 4147200,
28606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn4194304, 4199040, 4218750, 4251528, 4320000, 4374000, 4423680, 4428675, 4478976,
28616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn4500000, 4556250, 4608000, 4665600, 4687500, 4718592, 4723920, 4782969, 4800000,
28626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn4860000, 4915200, 4920750, 4976640, 5000000, 5038848, 5062500, 5120000, 5184000,
28636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn5242880, 5248800, 5308416, 5314410, 5400000, 5467500, 5529600, 5598720, 5625000,
28646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn5668704, 5760000, 5832000, 5859375, 5898240, 5904900, 5971968, 6000000, 6075000,
28656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn6144000, 6220800, 6250000, 6291456, 6298560, 6328125, 6377292, 6400000, 6480000,
28666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn6553600, 6561000, 6635520, 6718464, 6750000, 6834375, 6912000, 6998400, 7031250,
28676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn7077888, 7085880, 7200000, 7290000, 7372800, 7381125, 7464960, 7500000, 7558272,
28686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn7593750, 7680000, 7776000, 7812500, 7864320, 7873200, 7962624, 7971615, 8000000,
28696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn8100000, 8192000, 8201250, 8294400, 8388608, 8398080, 8437500, 8503056, 8640000,
28706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn8748000, 8847360, 8857350, 8957952, 9000000, 9112500, 9216000, 9331200, 9375000,
28716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn9437184, 9447840, 9565938, 9600000, 9720000, 9765625, 9830400, 9841500, 9953280,
28726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn10000000, 10077696, 10125000, 10240000, 10368000, 10485760, 10497600, 10546875, 10616832,
28736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn10628820, 10800000, 10935000, 11059200, 11197440, 11250000, 11337408, 11390625, 11520000,
28746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn11664000, 11718750, 11796480, 11809800, 11943936, 12000000, 12150000, 12288000, 12301875,
28756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn12441600, 12500000, 12582912, 12597120, 12656250, 12754584, 12800000, 12960000, 13107200,
28766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn13122000, 13271040, 13286025, 13436928, 13500000, 13668750, 13824000, 13996800, 14062500,
28776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn14155776, 14171760, 14400000, 14580000, 14745600, 14762250, 14929920, 15000000, 15116544,
28786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn15187500, 15360000, 15552000, 15625000, 15728640, 15746400, 15925248, 15943230, 16000000,
28796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn16200000, 16384000, 16402500, 16588800, 16777216, 16796160, 16875000, 17006112, 17280000,
28806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn17496000, 17578125, 17694720, 17714700, 17915904, 18000000, 18225000, 18432000, 18662400,
28816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn18750000, 18874368, 18895680, 18984375, 19131876, 19200000, 19440000, 19531250, 19660800,
28826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn19683000, 19906560, 20000000, 20155392, 20250000, 20480000, 20503125, 20736000, 20971520,
28836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn20995200, 21093750, 21233664, 21257640, 21600000, 21870000, 22118400, 22143375, 22394880,
28846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn22500000, 22674816, 22781250, 23040000, 23328000, 23437500, 23592960, 23619600, 23887872,
28856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn23914845, 24000000, 24300000, 24576000, 24603750, 24883200, 25000000, 25165824, 25194240,
28866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn25312500, 25509168, 25600000, 25920000, 26214400, 26244000, 26542080, 26572050, 26873856,
28876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn27000000, 27337500, 27648000, 27993600, 28125000, 28311552, 28343520, 28800000, 29160000,
28886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn29296875, 29491200, 29524500, 29859840, 30000000, 30233088, 30375000, 30720000, 31104000,
28896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn31250000, 31457280, 31492800, 31640625, 31850496, 31886460, 32000000, 32400000, 32768000,
28906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn32805000, 33177600, 33554432, 33592320, 33750000, 34012224, 34171875, 34560000, 34992000,
28916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn35156250, 35389440, 35429400, 35831808, 36000000, 36450000, 36864000, 36905625, 37324800,
28926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn37500000, 37748736, 37791360, 37968750, 38263752, 38400000, 38880000, 39062500, 39321600,
28936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn39366000, 39813120, 39858075, 40000000, 40310784, 40500000, 40960000, 41006250, 41472000,
28946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn41943040, 41990400, 42187500, 42467328, 42515280, 43200000, 43740000, 44236800, 44286750,
28956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn44789760, 45000000, 45349632, 45562500, 46080000, 46656000, 46875000, 47185920, 47239200,
28966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn47775744, 47829690, 48000000, 48600000, 48828125, 49152000, 49207500, 49766400, 50000000,
28976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn50331648, 50388480, 50625000, 51018336, 51200000, 51840000, 52428800, 52488000, 52734375,
28986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn53084160, 53144100, 53747712, 54000000, 54675000, 55296000, 55987200, 56250000, 56623104,
28996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn56687040, 56953125, 57600000, 58320000, 58593750, 58982400, 59049000, 59719680, 60000000,
29006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn60466176, 60750000, 61440000, 61509375, 62208000, 62500000, 62914560, 62985600, 63281250,
29016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn63700992, 63772920, 64000000, 64800000, 65536000, 65610000, 66355200, 66430125, 67108864,
29026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn67184640, 67500000, 68024448, 68343750, 69120000, 69984000, 70312500, 70778880, 70858800,
29036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn71663616, 72000000, 72900000, 73728000, 73811250, 74649600, 75000000, 75497472, 75582720,
29046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn75937500, 76527504, 76800000, 77760000, 78125000, 78643200, 78732000, 79626240, 79716150,
29056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn80000000, 80621568, 81000000, 81920000, 82012500, 82944000, 83886080, 83980800, 84375000,
29066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn84934656, 85030560, 86400000, 87480000, 87890625, 88473600, 88573500, 89579520, 90000000,
29076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn90699264, 91125000, 92160000, 93312000, 93750000, 94371840, 94478400, 94921875, 95551488,
29086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn95659380, 96000000, 97200000, 97656250, 98304000, 98415000, 99532800, 100000000,
29096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn100663296, 100776960, 101250000, 102036672, 102400000, 102515625, 103680000, 104857600,
29106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn104976000, 105468750, 106168320, 106288200, 107495424, 108000000, 109350000, 110592000,
29116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn110716875, 111974400, 112500000, 113246208, 113374080, 113906250, 115200000, 116640000,
29126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn117187500, 117964800, 118098000, 119439360, 119574225, 120000000, 120932352, 121500000,
29136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn122880000, 123018750, 124416000, 125000000, 125829120, 125971200, 126562500, 127401984,
29146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn127545840, 128000000, 129600000, 131072000, 131220000, 132710400, 132860250, 134217728,
29156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn134369280, 135000000, 136048896, 136687500, 138240000, 139968000, 140625000, 141557760,
29166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn141717600, 143327232, 144000000, 145800000, 146484375, 147456000, 147622500, 149299200,
29176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn150000000, 150994944, 151165440, 151875000, 153055008, 153600000, 155520000, 156250000,
29186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn157286400, 157464000, 158203125, 159252480, 159432300, 160000000, 161243136, 162000000,
29196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn163840000, 164025000, 165888000, 167772160, 167961600, 168750000, 169869312, 170061120,
29206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn170859375, 172800000, 174960000, 175781250, 176947200, 177147000, 179159040, 180000000,
29216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn181398528, 182250000, 184320000, 184528125, 186624000, 187500000, 188743680, 188956800,
29226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn189843750, 191102976, 191318760, 192000000, 194400000, 195312500, 196608000, 196830000,
29236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn199065600, 199290375, 200000000, 201326592, 201553920, 202500000, 204073344, 204800000,
29246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn205031250, 207360000, 209715200, 209952000, 210937500, 212336640, 212576400, 214990848,
29256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn216000000, 218700000, 221184000, 221433750, 223948800, 225000000, 226492416, 226748160,
29266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn227812500, 230400000, 233280000, 234375000, 235929600, 236196000, 238878720, 239148450,
29276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn240000000, 241864704, 243000000, 244140625, 245760000, 246037500, 248832000, 250000000,
29286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn251658240, 251942400, 253125000, 254803968, 255091680, 256000000, 259200000, 262144000,
29296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn262440000, 263671875, 265420800, 265720500, 268435456, 268738560, 270000000, 272097792,
29306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn273375000, 276480000, 279936000, 281250000, 283115520, 283435200, 284765625, 286654464,
29316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn288000000, 291600000, 292968750, 294912000, 295245000, 298598400, 300000000, 301989888,
29326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn302330880, 303750000, 306110016, 307200000, 307546875, 311040000, 312500000, 314572800,
29336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn314928000, 316406250, 318504960, 318864600, 320000000, 322486272, 324000000, 327680000,
29346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn328050000, 331776000, 332150625, 335544320, 335923200, 337500000, 339738624, 340122240,
29356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn341718750, 345600000, 349920000, 351562500, 353894400, 354294000, 358318080, 360000000,
29366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn362797056, 364500000, 368640000, 369056250, 373248000, 375000000, 377487360, 377913600,
29376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn379687500, 382205952, 382637520, 384000000, 388800000, 390625000, 393216000, 393660000,
29386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn398131200, 398580750, 400000000, 402653184, 403107840, 405000000, 408146688, 409600000,
29396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn410062500, 414720000, 419430400, 419904000, 421875000, 424673280, 425152800, 429981696,
29406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn432000000, 437400000, 439453125, 442368000, 442867500, 447897600, 450000000, 452984832,
29416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn453496320, 455625000, 460800000, 466560000, 468750000, 471859200, 472392000, 474609375,
29426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn477757440, 478296900, 480000000, 483729408, 486000000, 488281250, 491520000, 492075000,
29436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn497664000, 500000000, 503316480, 503884800, 506250000, 509607936, 510183360, 512000000,
29446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn512578125, 518400000, 524288000, 524880000, 527343750, 530841600, 531441000, 536870912,
29456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn537477120, 540000000, 544195584, 546750000, 552960000, 553584375, 559872000, 562500000,
29466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn566231040, 566870400, 569531250, 573308928, 576000000, 583200000, 585937500, 589824000,
29476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn590490000, 597196800, 597871125, 600000000, 603979776, 604661760, 607500000, 612220032,
29486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn614400000, 615093750, 622080000, 625000000, 629145600, 629856000, 632812500, 637009920,
29496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn637729200, 640000000, 644972544, 648000000, 655360000, 656100000, 663552000, 664301250,
29506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn671088640, 671846400, 675000000, 679477248, 680244480, 683437500, 691200000, 699840000,
29516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn703125000, 707788800, 708588000, 716636160, 720000000, 725594112, 729000000, 732421875,
29526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn737280000, 738112500, 746496000, 750000000, 754974720, 755827200, 759375000, 764411904,
29536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn765275040, 768000000, 777600000, 781250000, 786432000, 787320000, 791015625, 796262400,
29546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn797161500, 800000000, 805306368, 806215680, 810000000, 816293376, 819200000, 820125000,
29556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn829440000, 838860800, 839808000, 843750000, 849346560, 850305600, 854296875, 859963392,
29566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn864000000, 874800000, 878906250, 884736000, 885735000, 895795200, 900000000, 905969664,
29576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn906992640, 911250000, 921600000, 922640625, 933120000, 937500000, 943718400, 944784000,
29586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn949218750, 955514880, 956593800, 960000000, 967458816, 972000000, 976562500, 983040000,
29596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn984150000, 995328000, 996451875, 1000000000, 1006632960, 1007769600, 1012500000,
29606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn1019215872, 1020366720, 1024000000, 1025156250, 1036800000, 1048576000, 1049760000,
29616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn1054687500, 1061683200, 1062882000, 1073741824, 1074954240, 1080000000, 1088391168,
29626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn1093500000, 1105920000, 1107168750, 1119744000, 1125000000, 1132462080, 1133740800,
29636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn1139062500, 1146617856, 1152000000, 1166400000, 1171875000, 1179648000, 1180980000,
29646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn1194393600, 1195742250, 1200000000, 1207959552, 1209323520, 1215000000, 1220703125,
29656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn1224440064, 1228800000, 1230187500, 1244160000, 1250000000, 1258291200, 1259712000,
29666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn1265625000, 1274019840, 1275458400, 1280000000, 1289945088, 1296000000, 1310720000,
29676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn1312200000, 1318359375, 1327104000, 1328602500, 1342177280, 1343692800, 1350000000,
29686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn1358954496, 1360488960, 1366875000, 1382400000, 1399680000, 1406250000, 1415577600,
29696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn1417176000, 1423828125, 1433272320, 1440000000, 1451188224, 1458000000, 1464843750,
29706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn1474560000, 1476225000, 1492992000, 1500000000, 1509949440, 1511654400, 1518750000,
29716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn1528823808, 1530550080, 1536000000, 1537734375, 1555200000, 1562500000, 1572864000,
29726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn1574640000, 1582031250, 1592524800, 1594323000, 1600000000, 1610612736, 1612431360,
29736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn1620000000, 1632586752, 1638400000, 1640250000, 1658880000, 1660753125, 1677721600,
29746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn1679616000, 1687500000, 1698693120, 1700611200, 1708593750, 1719926784, 1728000000,
29756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn1749600000, 1757812500, 1769472000, 1771470000, 1791590400, 1800000000, 1811939328,
29766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn1813985280, 1822500000, 1843200000, 1845281250, 1866240000, 1875000000, 1887436800,
29776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn1889568000, 1898437500, 1911029760, 1913187600, 1920000000, 1934917632, 1944000000,
29786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn1953125000, 1966080000, 1968300000, 1990656000, 1992903750, 2000000000, 2013265920,
29796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn2015539200, 2025000000, 2038431744, 2040733440, 2048000000, 2050312500, 2073600000,
29806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn2097152000, 2099520000, 2109375000, 2123366400, 2125764000
29816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn};
29826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
29836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
29846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL int
29856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvGetOptimalDFTSize( int size0 )
29866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
29876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int a = 0, b = sizeof(icvOptimalDFTSize)/sizeof(icvOptimalDFTSize[0]) - 1;
29886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( (unsigned)size0 >= (unsigned)icvOptimalDFTSize[b] )
29896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return -1;
29906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
29916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    while( a < b )
29926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
29936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int c = (a + b) >> 1;
29946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( size0 <= icvOptimalDFTSize[c] )
29956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            b = c;
29966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        else
29976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            a = c+1;
29986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
29996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
30006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return icvOptimalDFTSize[b];
30016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
30026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
30036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* End of file. */
3004