1 /*M///////////////////////////////////////////////////////////////////////////////////////
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install,
7 // copy or use the software.
10 // Intel License Agreement
11 // For Open Source Computer Vision Library
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
19 // * Redistribution's of source code must retain the above copyright notice,
20 // this list of conditions and the following disclaimer.
22 // * Redistribution's in binary form must reproduce the above copyright notice,
23 // this list of conditions and the following disclaimer in the documentation
24 // and/or other materials provided with the distribution.
26 // * The name of Intel Corporation may not be used to endorse or promote products
27 // derived from this software without specific prior written permission.
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the Intel Corporation or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
42 //////////////////////////////////////////////////////////////////////////////////////////
43 ////////////////// tests for discrete linear transforms (FFT, DCT ...) ///////////////////
44 //////////////////////////////////////////////////////////////////////////////////////////
46 #include "cxcoretest.h"
49 typedef struct CvTsComplex32f
55 typedef struct CvTsComplex64f
61 static CvMat* cvTsInitDFTWave( int n, int inv )
64 double angle = (inv ? 1 : -1)*CV_PI*2/n;
65 CvTsComplex64f wi, w1;
66 CvMat* wave = cvCreateMat( 1, n, CV_64FC2 );
67 CvTsComplex64f* w = (CvTsComplex64f*)wave->data.db;
74 for( i = 1; i < n; i++ )
76 double t = wi.re*w1.re - wi.im*w1.im;
77 wi.im = wi.re*w1.im + wi.im*w1.re;
86 static void cvTsDFT_1D( const CvMat* _src, CvMat* _dst, int flags, CvMat* wave=0 )
88 int i, j, k, n = _dst->cols + _dst->rows - 1;
89 const CvMat* wave0 = wave;
90 double scale = (flags & CV_DXT_SCALE) ? 1./n : 1.;
91 assert( _src->cols + _src->rows - 1 == n );
92 int src_step = 1, dst_step = 1;
95 assert( CV_ARE_TYPES_EQ(_src,_dst) && _src->rows*_src->cols == _dst->rows*_dst->cols );
98 wave = cvTsInitDFTWave( n, flags & CV_DXT_INVERSE );
100 w = (CvTsComplex64f*)wave->data.db;
101 if( !CV_IS_MAT_CONT(_src->type) )
102 src_step = _src->step/CV_ELEM_SIZE(_src->type);
103 if( !CV_IS_MAT_CONT(_dst->type) )
104 dst_step = _dst->step/CV_ELEM_SIZE(_dst->type);
106 if( CV_MAT_TYPE(_src->type) == CV_32FC2 )
108 CvTsComplex32f* dst = (CvTsComplex32f*)_dst->data.fl;
109 for( i = 0; i < n; i++, dst += dst_step )
111 CvTsComplex32f* src = (CvTsComplex32f*)_src->data.fl;
112 CvTsComplex64f sum = {0,0};
116 for( j = 0; j < n; j++, src += src_step )
118 sum.re += src->re*w[k].re - src->im*w[k].im;
119 sum.im += src->re*w[k].im + src->im*w[k].re;
121 k -= (k >= n ? n : 0);
124 dst->re = (float)(sum.re*scale);
125 dst->im = (float)(sum.im*scale);
128 else if( CV_MAT_TYPE(_src->type) == CV_64FC2 )
130 CvTsComplex64f* dst = (CvTsComplex64f*)_dst->data.db;
131 for( i = 0; i < n; i++, dst += dst_step )
133 CvTsComplex64f* src = (CvTsComplex64f*)_src->data.db;
134 CvTsComplex64f sum = {0,0};
138 for( j = 0; j < n; j++, src += src_step )
140 sum.re += src->re*w[k].re - src->im*w[k].im;
141 sum.im += src->re*w[k].im + src->im*w[k].re;
143 k -= (k >= n ? n : 0);
146 dst->re = sum.re*scale;
147 dst->im = sum.im*scale;
154 cvReleaseMat( &wave );
158 static void cvTsDFT_2D( const CvMat* src, CvMat* dst, int flags )
161 CvMat* tmp = cvCreateMat( dst->cols, dst->rows, dst->type );
162 CvMat* wave = cvTsInitDFTWave( dst->cols, flags & CV_DXT_INVERSE );
164 // 1. row-wise transform
165 for( i = 0; i < dst->rows; i++ )
167 CvMat src_row, dst_row;
168 cvGetRow( src, &src_row, i );
169 cvGetCol( tmp, &dst_row, i );
170 cvTsDFT_1D( &src_row, &dst_row, flags, wave );
173 if( !(flags & CV_DXT_ROWS) )
175 if( dst->cols != dst->rows )
177 cvReleaseMat( &wave );
178 wave = cvTsInitDFTWave( dst->rows, flags & CV_DXT_INVERSE );
181 // 2. column-wise transform
182 for( i = 0; i < dst->cols; i++ )
184 CvMat src_row, dst_row;
185 cvGetRow( tmp, &src_row, i );
186 cvGetCol( dst, &dst_row, i );
187 cvTsDFT_1D( &src_row, &dst_row, flags, wave );
191 cvTsTranspose( tmp, dst );
193 cvReleaseMat( &wave );
194 cvReleaseMat( &tmp );
198 static CvMat* cvTsInitDCTWave( int n, int inv )
201 double angle = CV_PI*0.5/n;
202 CvMat* wave = cvCreateMat( n, n, CV_64FC1 );
204 double scale = sqrt(1./n);
205 for( k = 0; k < n; k++ )
206 wave->data.db[k] = scale;
208 for( i = 1; i < n; i++ )
209 for( k = 0; k < n; k++ )
210 wave->data.db[i*n + k] = scale*cos( angle*i*(2*k + 1) );
213 cvTsTranspose( wave, wave );
219 static void cvTsDCT_1D( const CvMat* _src, CvMat* _dst, int flags, CvMat* wave=0 )
221 int i, j, n = _dst->cols + _dst->rows - 1;
222 const CvMat* wave0 = wave;
223 assert( _src->cols + _src->rows - 1 == n);
224 int src_step = 1, dst_step = 1;
227 assert( CV_ARE_TYPES_EQ(_src,_dst) && _src->rows*_src->cols == _dst->rows*_dst->cols );
230 wave = cvTsInitDCTWave( n, flags & CV_DXT_INVERSE );
233 if( !CV_IS_MAT_CONT(_src->type) )
234 src_step = _src->step/CV_ELEM_SIZE(_src->type);
235 if( !CV_IS_MAT_CONT(_dst->type) )
236 dst_step = _dst->step/CV_ELEM_SIZE(_dst->type);
238 if( CV_MAT_TYPE(_src->type) == CV_32FC1 )
240 float *dst = _dst->data.fl;
242 for( i = 0; i < n; i++, dst += dst_step )
244 const float* src = _src->data.fl;
247 for( j = 0; j < n; j++, src += src_step )
253 else if( CV_MAT_TYPE(_src->type) == CV_64FC1 )
255 double *dst = _dst->data.db;
257 for( i = 0; i < n; i++, dst += dst_step )
259 const double* src = _src->data.db;
262 for( j = 0; j < n; j++, src += src_step )
272 cvReleaseMat( &wave );
276 static void cvTsDCT_2D( const CvMat* src, CvMat* dst, int flags )
279 CvMat* tmp = cvCreateMat( dst->cols, dst->rows, dst->type );
280 CvMat* wave = cvTsInitDCTWave( dst->cols, flags & CV_DXT_INVERSE );
282 // 1. row-wise transform
283 for( i = 0; i < dst->rows; i++ )
285 CvMat src_row, dst_row;
286 cvGetRow( src, &src_row, i );
287 cvGetCol( tmp, &dst_row, i );
288 cvTsDCT_1D( &src_row, &dst_row, flags, wave );
291 if( !(flags & CV_DXT_ROWS) )
293 if( dst->cols != dst->rows )
295 cvReleaseMat( &wave );
296 wave = cvTsInitDCTWave( dst->rows, flags & CV_DXT_INVERSE );
299 // 2. column-wise transform
300 for( i = 0; i < dst->cols; i++ )
302 CvMat src_row, dst_row;
303 cvGetRow( tmp, &src_row, i );
304 cvGetCol( dst, &dst_row, i );
305 cvTsDCT_1D( &src_row, &dst_row, flags, wave );
310 cvTranspose( tmp, dst );
313 cvReleaseMat( &wave );
314 cvReleaseMat( &tmp );
318 static void cvTsConvertFromCCS( const CvMat* _src0, const CvMat* _src1,
319 CvMat* _dst, int flags )
321 if( _dst->rows > 1 && (_dst->cols > 1 || (flags & CV_DXT_ROWS)) )
323 int i, count = _dst->rows, len = _dst->cols;
324 int is_2d = (flags & CV_DXT_ROWS) == 0;
325 CvMat src0_row, src1_row, dst_row;
326 for( i = 0; i < count; i++ )
328 int j = !is_2d || i == 0 ? i : count - i;
329 cvGetRow( _src0, &src0_row, i );
330 cvGetRow( _src1, &src1_row, j );
331 cvGetRow( _dst, &dst_row, i );
332 cvTsConvertFromCCS( &src0_row, &src1_row, &dst_row, 0 );
337 cvGetCol( _src0, &src0_row, 0 );
338 cvGetCol( _dst, &dst_row, 0 );
339 cvTsConvertFromCCS( &src0_row, &src0_row, &dst_row, 0 );
342 cvGetCol( _src0, &src0_row, _src0->cols - 1 );
343 cvGetCol( _dst, &dst_row, len/2 );
344 cvTsConvertFromCCS( &src0_row, &src0_row, &dst_row, 0 );
350 int i, n = _dst->cols + _dst->rows - 1, n2 = (n+1) >> 1;
351 int cn = CV_MAT_CN(_src0->type);
352 int src_step = cn, dst_step = 1;
354 if( !CV_IS_MAT_CONT(_dst->type) )
355 dst_step = _dst->step/CV_ELEM_SIZE(_dst->type);
357 if( !CV_IS_MAT_CONT(_src0->type) )
358 src_step = _src0->step/CV_ELEM_SIZE(_src0->type & CV_MAT_DEPTH_MASK);
360 if( CV_MAT_DEPTH(_dst->type) == CV_32F )
362 CvTsComplex32f* dst = (CvTsComplex32f*)_dst->data.fl;
363 const float* src0 = _src0->data.fl;
364 const float* src1 = _src1->data.fl;
372 dst[n2*dst_step].re = src0[(cn == 1 ? n-1 : n2)*src_step];
373 dst[n2*dst_step].im = 0;
377 delta1 = delta0 + (cn == 1 ? src_step : 1);
381 for( i = 1; i < n2; i++, delta0 += src_step, delta1 += src_step )
383 float t0 = src0[delta0];
384 float t1 = src0[delta1];
386 dst[i*dst_step].re = t0;
387 dst[i*dst_step].im = t1;
392 dst[(n-i)*dst_step].re = t0;
393 dst[(n-i)*dst_step].im = t1;
398 CvTsComplex64f* dst = (CvTsComplex64f*)_dst->data.db;
399 const double* src0 = _src0->data.db;
400 const double* src1 = _src1->data.db;
408 dst[n2*dst_step].re = src0[(cn == 1 ? n-1 : n2)*src_step];
409 dst[n2*dst_step].im = 0;
413 delta1 = delta0 + (cn == 1 ? src_step : 1);
417 for( i = 1; i < n2; i++, delta0 += src_step, delta1 += src_step )
419 double t0 = src0[delta0];
420 double t1 = src0[delta1];
422 dst[i*dst_step].re = t0;
423 dst[i*dst_step].im = t1;
428 dst[(n-i)*dst_step].re = t0;
429 dst[(n-i)*dst_step].im = t1;
436 static void cvTsFixCCS( CvMat* mat, int cols, int flags )
438 int i, rows = mat->rows;
439 int rows2 = flags & CV_DXT_ROWS ? rows : rows/2 + 1, cols2 = cols/2 + 1;
441 assert( cols2 == mat->cols );
443 if( CV_MAT_TYPE(mat->type) == CV_32FC2 )
445 for( i = 0; i < rows2; i++ )
447 CvTsComplex32f* row = (CvTsComplex32f*)(mat->data.ptr + mat->step*i);
448 if( (flags & CV_DXT_ROWS) || i == 0 || i == rows2 - 1 && rows % 2 == 0 )
456 CvTsComplex32f* row2 = (CvTsComplex32f*)(mat->data.ptr + mat->step*(rows-i));
457 row2[0].re = row[0].re;
458 row2[0].im = -row[0].im;
462 row2[cols2-1].re = row[cols2-1].re;
463 row2[cols2-1].im = -row[cols2-1].im;
468 else if( CV_MAT_TYPE(mat->type) == CV_64FC2 )
470 for( i = 0; i < rows2; i++ )
472 CvTsComplex64f* row = (CvTsComplex64f*)(mat->data.ptr + mat->step*i);
473 if( (flags & CV_DXT_ROWS) || i == 0 || i == rows2 - 1 && rows % 2 == 0 )
481 CvTsComplex64f* row2 = (CvTsComplex64f*)(mat->data.ptr + mat->step*(rows-i));
482 row2[0].re = row[0].re;
483 row2[0].im = -row[0].im;
487 row2[cols2-1].re = row[cols2-1].re;
488 row2[cols2-1].im = -row[cols2-1].im;
496 static const CvSize dxt_sizes[] = {{16,1}, {256,1}, {1024,1}, {65536,1},
497 {10,1}, {100,1}, {1000,1}, {100000,1}, {256, 256}, {1024,1024}, {-1,-1}};
498 static const int dxt_depths[] = { CV_32F, CV_64F, -1 };
499 static const char* dxt_param_names[] = { "size", "depth", "transform_type", 0 };
500 static const char* dft_transforms[] = { "Fwd_CToC", "Inv_CToC", "Fwd_RToPack", "Inv_PackToR", 0 };
501 static const char* mulsp_transforms[] = { "Fwd_CToC", "Fwd_RToPack", 0 };
502 static const char* dct_transforms[] = { "Fwd", "Inv", 0 };
504 class CxCore_DXTBaseTestImpl : public CvArrTest
507 CxCore_DXTBaseTestImpl( const char* test_name, const char* test_funcs,
508 bool _allow_complex=false, bool _allow_odd=false,
509 bool _spectrum_mode=false );
511 void get_test_array_types_and_sizes( int test_case_idx, CvSize** sizes, int** types );
512 int prepare_test_case( int test_case_idx );
513 double get_success_error_level( int /*test_case_idx*/, int /*i*/, int /*j*/ );
514 void get_timing_test_array_types_and_sizes( int test_case_idx,
515 CvSize** sizes, int** types,
516 CvSize** whole_sizes, bool* are_images );
517 void print_timing_params( int test_case_idx, char* ptr, int params_left );
518 int write_default_params( CvFileStorage* fs );
519 int flags; // transformation flags
520 bool allow_complex, // whether input/output may be complex or not:
521 // true for DFT and MulSpectrums, false for DCT
522 allow_odd, // whether input/output may be have odd (!=1) dimensions:
523 // true for DFT and MulSpectrums, false for DCT
524 spectrum_mode, // (2 complex/ccs inputs, 1 complex/ccs output):
525 // true for MulSpectrums, false for DFT and DCT
526 inplace, // inplace operation (set for each individual test case)
527 temp_dst; // use temporary destination (for real->ccs DFT and ccs MulSpectrums)
528 const char** transform_type_list;
532 CxCore_DXTBaseTestImpl::CxCore_DXTBaseTestImpl( const char* test_name, const char* test_funcs,
533 bool _allow_complex, bool _allow_odd, bool _spectrum_mode )
534 : CvArrTest( test_name, test_funcs, "" ),
535 flags(0), allow_complex(_allow_complex), allow_odd(_allow_odd),
536 spectrum_mode(_spectrum_mode), inplace(false), temp_dst(false)
538 test_array[INPUT].push(NULL);
540 test_array[INPUT].push(NULL);
541 test_array[OUTPUT].push(NULL);
542 test_array[REF_OUTPUT].push(NULL);
543 test_array[TEMP].push(NULL);
544 test_array[TEMP].push(NULL);
546 element_wise_relative_error = spectrum_mode;
548 size_list = (CvSize*)dxt_sizes;
550 depth_list = (int*)dxt_depths;
552 transform_type_list = 0;
556 void CxCore_DXTBaseTestImpl::get_test_array_types_and_sizes( int test_case_idx,
557 CvSize** sizes, int** types )
559 CvRNG* rng = ts->get_rng();
560 int bits = cvTsRandInt(rng);
561 int depth = cvTsRandInt(rng)%2 + CV_32F;
562 int cn = !allow_complex || !(bits & 256) ? 1 : 2;
564 CvArrTest::get_test_array_types_and_sizes( test_case_idx, sizes, types );
566 flags = bits & (CV_DXT_INVERSE | CV_DXT_SCALE | CV_DXT_ROWS | CV_DXT_MUL_CONJ);
568 flags &= ~CV_DXT_INVERSE;
569 types[TEMP][0] = types[TEMP][1] = types[INPUT][0] =
570 types[OUTPUT][0] = CV_MAKETYPE(depth, cn);
571 size = sizes[INPUT][0];
573 //size.width = size.width % 10 + 1;
574 //size.height = size.width % 10 + 1;
576 //flags &= ~CV_DXT_ROWS;
579 if( flags & CV_DXT_ROWS && (bits&1024) )
585 flags &= ~CV_DXT_ROWS;
590 if( size.width > 1 && (size.width&1) != 0 )
591 size.width = (size.width + 1) & -2;
593 if( size.height > 1 && (size.height&1) != 0 && !(flags & CV_DXT_ROWS) )
594 size.height = (size.height + 1) & -2;
597 sizes[INPUT][0] = sizes[OUTPUT][0] = size;
598 sizes[TEMP][0] = sizes[TEMP][1] = cvSize(0,0);
604 types[OUTPUT][0] = depth + 8;
605 sizes[TEMP][0] = size;
607 sizes[INPUT][0] = sizes[INPUT][1] = size;
608 types[INPUT][1] = types[INPUT][0];
610 else if( cn == 2 && (bits&32) || cn == 1 && allow_complex )
612 types[TEMP][0] = depth + 8; // CV_??FC2
613 sizes[TEMP][0] = size;
614 size = cvSize(size.width/2+1, size.height);
616 if( flags & CV_DXT_INVERSE )
620 types[OUTPUT][0] = depth;
621 sizes[INPUT][0] = size;
623 types[TEMP][1] = types[TEMP][0];
624 sizes[TEMP][1] = sizes[TEMP][0];
629 types[OUTPUT][0] = depth + 8;
633 types[INPUT][0] = depth;
634 types[TEMP][1] = types[TEMP][0];
635 sizes[TEMP][1] = size;
639 types[TEMP][1] = depth;
640 sizes[TEMP][1] = sizes[TEMP][0];
648 !temp_dst && types[INPUT][0] == types[OUTPUT][0] ||
649 temp_dst && types[INPUT][0] == types[TEMP][1] )
650 inplace = (bits & 64) != 0;
652 types[REF_OUTPUT][0] = types[OUTPUT][0];
653 sizes[REF_OUTPUT][0] = sizes[OUTPUT][0];
657 void CxCore_DXTBaseTestImpl::get_timing_test_array_types_and_sizes( int test_case_idx,
658 CvSize** sizes, int** types,
659 CvSize** whole_sizes, bool* are_images )
661 CvArrTest::get_timing_test_array_types_and_sizes( test_case_idx,
662 sizes, types, whole_sizes, are_images );
663 const char* transform_type = cvReadString( find_timing_param( "transform_type" ), "" );
664 int depth = CV_MAT_DEPTH(types[INPUT][0]);
665 int in_type = depth, out_type = depth;
667 if( strcmp( transform_type, "Fwd_CToC" ) == 0 || strcmp( transform_type, "Inv_CToC" ) == 0 )
668 in_type = out_type = CV_MAKETYPE(depth,2);
670 if( strncmp( transform_type, "Fwd", 3 ) == 0 )
671 flags = CV_DXT_FORWARD;
673 flags = CV_DXT_INV_SCALE;
675 types[INPUT][0] = in_type;
677 types[INPUT][1] = in_type;
678 types[OUTPUT][0] = types[REF_OUTPUT][0] = out_type;
679 sizes[TEMP][0] = cvSize(0,0);
685 int CxCore_DXTBaseTestImpl::write_default_params( CvFileStorage* fs )
687 int code = CvArrTest::write_default_params(fs);
688 if( code < 0 || ts->get_testing_mode() != CvTS::TIMING_MODE )
690 write_string_list( fs, "transform_type", transform_type_list );
695 void CxCore_DXTBaseTestImpl::print_timing_params( int test_case_idx, char* ptr, int params_left )
697 sprintf( ptr, "%s,", cvReadString( find_timing_param("transform_type"), "" ) );
700 CvArrTest::print_timing_params( test_case_idx, ptr, params_left );
704 double CxCore_DXTBaseTestImpl::get_success_error_level( int test_case_idx, int i, int j )
706 return CvArrTest::get_success_error_level( test_case_idx, i, j );
710 int CxCore_DXTBaseTestImpl::prepare_test_case( int test_case_idx )
712 int code = CvArrTest::prepare_test_case( test_case_idx );
713 if( code > 0 && ts->get_testing_mode() == CvTS::CORRECTNESS_CHECK_MODE )
715 int in_type = CV_MAT_TYPE(test_mat[INPUT][0].type);
716 int out_type = CV_MAT_TYPE(test_mat[OUTPUT][0].type);
718 if( CV_MAT_CN(in_type) == 2 && CV_MAT_CN(out_type) == 1 )
719 cvTsFixCCS( &test_mat[INPUT][0], test_mat[OUTPUT][0].cols, flags );
722 cvTsCopy( &test_mat[INPUT][test_case_idx & (int)spectrum_mode],
723 temp_dst ? &test_mat[TEMP][1] :
724 in_type == out_type ? &test_mat[OUTPUT][0] :
725 &test_mat[TEMP][0] );
731 CxCore_DXTBaseTestImpl dxt_test( "dxt", "" );
734 class CxCore_DXTBaseTest : public CxCore_DXTBaseTestImpl
737 CxCore_DXTBaseTest( const char* test_name, const char* test_funcs,
738 bool _allow_complex=false, bool _allow_odd=false,
739 bool _spectrum_mode=false );
742 CxCore_DXTBaseTest::CxCore_DXTBaseTest( const char* test_name, const char* test_funcs,
743 bool _allow_complex, bool _allow_odd, bool _spectrum_mode )
744 : CxCore_DXTBaseTestImpl( test_name, test_funcs, _allow_complex, _allow_odd, _spectrum_mode )
748 default_timing_param_names = dxt_param_names;
749 transform_type_list = dft_transforms;
753 ////////////////////// FFT ////////////////////////
754 class CxCore_DFTTest : public CxCore_DXTBaseTest
760 void prepare_to_validation( int test_case_idx );
764 CxCore_DFTTest::CxCore_DFTTest() : CxCore_DXTBaseTest( "dxt-dft", "cvDFT", true, true, false )
769 void CxCore_DFTTest::run_func()
771 CvArr* dst = temp_dst ? test_array[TEMP][1] : test_array[OUTPUT][0];
772 CvArr* src = inplace ? dst : test_array[INPUT][0];
774 cvDFT( src, dst, flags );
778 void CxCore_DFTTest::prepare_to_validation( int /*test_case_idx*/ )
780 CvMat* src = &test_mat[INPUT][0];
781 CvMat* dst = &test_mat[REF_OUTPUT][0];
782 CvMat* tmp_src = src;
783 CvMat* tmp_dst = dst;
784 int src_cn = CV_MAT_CN( src->type );
785 int dst_cn = CV_MAT_CN( dst->type );
787 if( src_cn != 2 || dst_cn != 2 )
789 tmp_src = &test_mat[TEMP][0];
791 if( !(flags & CV_DXT_INVERSE ) )
793 CvMat* cvdft_dst = &test_mat[TEMP][1];
794 cvTsConvertFromCCS( cvdft_dst, cvdft_dst,
795 &test_mat[OUTPUT][0], flags );
797 cvTsInsert( src, tmp_src, 0 );
801 cvTsConvertFromCCS( src, src, tmp_src, flags );
802 tmp_dst = &test_mat[TEMP][1];
806 if( src->rows == 1 || (src->cols == 1 && !(flags & CV_DXT_ROWS)) )
807 cvTsDFT_1D( tmp_src, tmp_dst, flags );
809 cvTsDFT_2D( tmp_src, tmp_dst, flags );
812 cvTsExtract( tmp_dst, dst, 0 );
816 CxCore_DFTTest dft_test;
819 ////////////////////// DCT ////////////////////////
820 class CxCore_DCTTest : public CxCore_DXTBaseTest
826 void prepare_to_validation( int test_case_idx );
830 CxCore_DCTTest::CxCore_DCTTest() : CxCore_DXTBaseTest( "dxt-dct", "cvDCT", false, false, false )
832 transform_type_list = dct_transforms;
836 void CxCore_DCTTest::run_func()
838 CvArr* dst = test_array[OUTPUT][0];
839 CvArr* src = inplace ? dst : test_array[INPUT][0];
841 cvDCT( src, dst, flags );
845 void CxCore_DCTTest::prepare_to_validation( int /*test_case_idx*/ )
847 CvMat* src = &test_mat[INPUT][0];
848 CvMat* dst = &test_mat[REF_OUTPUT][0];
850 if( src->rows == 1 || (src->cols == 1 && !(flags & CV_DXT_ROWS)) )
851 cvTsDCT_1D( src, dst, flags );
853 cvTsDCT_2D( src, dst, flags );
857 CxCore_DCTTest dct_test;
860 ////////////////////// MulSpectrums ////////////////////////
861 class CxCore_MulSpectrumsTest : public CxCore_DXTBaseTest
864 CxCore_MulSpectrumsTest();
867 void prepare_to_validation( int test_case_idx );
871 CxCore_MulSpectrumsTest::CxCore_MulSpectrumsTest() :
872 CxCore_DXTBaseTest( "dxt-mulspectrums", "cvMulSpectrums", true, true, true )
874 transform_type_list = mulsp_transforms;
878 void CxCore_MulSpectrumsTest::run_func()
880 CvArr* dst = test_array[TEMP].size() > 0 && test_array[TEMP][0] ?
881 test_array[TEMP][0] : test_array[OUTPUT][0];
882 CvArr *src1 = test_array[INPUT][0], *src2 = test_array[INPUT][1];
886 if( ts->get_current_test_info()->test_case_idx & 1 )
892 cvMulSpectrums( src1, src2, dst, flags );
896 static void cvTsMulComplex( const CvMat* A, const CvMat* B, CvMat* C, int flags )
898 int i, j, depth = CV_MAT_DEPTH(A->type), cols = A->cols*2;
900 assert( CV_ARE_SIZES_EQ(A,B) && CV_ARE_SIZES_EQ(B,C) &&
901 CV_ARE_TYPES_EQ(A,B) && CV_ARE_TYPES_EQ(B,C) &&
902 CV_MAT_CN(A->type) == 2 && CV_MAT_DEPTH(A->type) >= CV_32F );
904 for( i = 0; i < C->rows; i++ )
906 if( depth == CV_32F )
908 const float* a = (float*)(A->data.ptr + A->step*i);
909 const float* b = (float*)(B->data.ptr + B->step*i);
910 float* c = (float*)(C->data.ptr + C->step*i);
912 if( !(flags & CV_DXT_MUL_CONJ) )
913 for( j = 0; j < cols; j += 2 )
915 double re = (double)a[j]*b[j] - (double)a[j+1]*b[j+1];
916 double im = (double)a[j+1]*b[j] + (double)a[j]*b[j+1];
922 for( j = 0; j < cols; j += 2 )
924 double re = (double)a[j]*b[j] + (double)a[j+1]*b[j+1];
925 double im = (double)a[j+1]*b[j] - (double)a[j]*b[j+1];
933 const double* a = (double*)(A->data.ptr + A->step*i);
934 const double* b = (double*)(B->data.ptr + B->step*i);
935 double* c = (double*)(C->data.ptr + C->step*i);
937 if( !(flags & CV_DXT_MUL_CONJ) )
938 for( j = 0; j < cols; j += 2 )
940 double re = a[j]*b[j] - a[j+1]*b[j+1];
941 double im = a[j+1]*b[j] + a[j]*b[j+1];
947 for( j = 0; j < cols; j += 2 )
949 double re = a[j]*b[j] + a[j+1]*b[j+1];
950 double im = a[j+1]*b[j] - a[j]*b[j+1];
960 void CxCore_MulSpectrumsTest::prepare_to_validation( int /*test_case_idx*/ )
962 CvMat* src1 = &test_mat[INPUT][0];
963 CvMat* src2 = &test_mat[INPUT][1];
964 CvMat* dst = &test_mat[OUTPUT][0];
965 CvMat* dst0 = &test_mat[REF_OUTPUT][0];
966 CvMat* temp = test_array[TEMP].size() > 0 && test_array[TEMP][0] ? &test_mat[TEMP][0] : 0;
967 int cn = CV_MAT_CN(src1->type);
971 cvTsConvertFromCCS( src1, src1, dst, flags );
972 cvTsConvertFromCCS( src2, src2, dst0, flags );
977 cvTsMulComplex( src1, src2, dst0, flags );
981 cvTsConvertFromCCS( temp, temp, dst, flags );
986 CxCore_MulSpectrumsTest mulspectrums_test;