libavcodec/dct-test.c
04d7f601
 /*
  * (c) 2001 Fabrice Bellard
3ac35bdb
  *     2007 Marc Hoffman <marc.hoffman@analog.com>
04d7f601
  *
b78e7197
  * This file is part of FFmpeg.
  *
  * FFmpeg is free software; you can redistribute it and/or
04d7f601
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
b78e7197
  * version 2.1 of the License, or (at your option) any later version.
04d7f601
  *
b78e7197
  * FFmpeg is distributed in the hope that it will be useful,
04d7f601
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
b78e7197
  * License along with FFmpeg; if not, write to the Free Software
04d7f601
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
983e3246
 /**
ba87f080
  * @file
94f694a4
  * DCT test (c) 2001 Fabrice Bellard
983e3246
  * Started from sample code by Juan J. Sierralta P.
  */
 
de6d9b64
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
 #include <sys/time.h>
 #include <unistd.h>
12807c8d
 #include <math.h>
de6d9b64
 
c6c98d08
 #include "libavutil/cpu.h"
ae32e509
 #include "libavutil/common.h"
294eaa26
 #include "libavutil/lfg.h"
de6d9b64
 
86748dbc
 #include "simple_idct.h"
10ac3618
 #include "aandcttab.h"
65e4c8c9
 #include "faandct.h"
6f08c541
 #include "faanidct.h"
a6493a8f
 #include "x86/idct_xvid.h"
6a813295
 #include "dctref.h"
9e1586fc
 
434df899
 #undef printf
 
9686df2b
 void ff_mmx_idct(DCTELEM *data);
 void ff_mmxext_idct(DCTELEM *data);
9e1586fc
 
9686df2b
 void odivx_idct_c(short *block);
86748dbc
 
3ac35bdb
 // BFIN
9686df2b
 void ff_bfin_idct(DCTELEM *block);
 void ff_bfin_fdct(DCTELEM *block);
3ac35bdb
 
 // ALTIVEC
9686df2b
 void fdct_altivec(DCTELEM *block);
 //void idct_altivec(DCTELEM *block);?? no routine
3ac35bdb
 
479044ce
 // ARM
0926c009
 void ff_j_rev_dct_arm(DCTELEM *data);
 void ff_simple_idct_arm(DCTELEM *data);
 void ff_simple_idct_armv5te(DCTELEM *data);
479044ce
 void ff_simple_idct_armv6(DCTELEM *data);
 void ff_simple_idct_neon(DCTELEM *data);
3ac35bdb
 
2a839eeb
 void ff_simple_idct_axp(DCTELEM *data);
 
3ac35bdb
 struct algo {
f5b67781
   const char *name;
3ac35bdb
   enum { FDCT, IDCT } is_idct;
   void (* func) (DCTELEM *block);
   void (* ref)  (DCTELEM *block);
875f3125
   enum formattag { NO_PERM,MMX_PERM, MMX_SIMPLE_PERM, SCALE_PERM, SSE2_PERM, PARTTRANS_PERM } format;
3794b928
   int  mm_support;
3ac35bdb
 };
 
 #ifndef FAAN_POSTSCALE
 #define FAAN_SCALE SCALE_PERM
 #else
 #define FAAN_SCALE NO_PERM
 #endif
 
aadd27cd
 static int cpu_flags;
 
3ac35bdb
 struct algo algos[] = {
0de74546
   {"REF-DBL",         0, ff_ref_fdct,        ff_ref_fdct, NO_PERM},
   {"FAAN",            0, ff_faandct,         ff_ref_fdct, FAAN_SCALE},
   {"FAANI",           1, ff_faanidct,        ff_ref_idct, NO_PERM},
   {"IJG-AAN-INT",     0, fdct_ifast,         ff_ref_fdct, SCALE_PERM},
   {"IJG-LLM-INT",     0, ff_jpeg_fdct_islow, ff_ref_fdct, NO_PERM},
   {"REF-DBL",         1, ff_ref_idct,        ff_ref_idct, NO_PERM},
   {"INT",             1, j_rev_dct,          ff_ref_idct, MMX_PERM},
   {"SIMPLE-C",        1, ff_simple_idct,     ff_ref_idct, NO_PERM},
3ac35bdb
 
b250f9c6
 #if HAVE_MMX
7160bb71
   {"MMX",             0, ff_fdct_mmx,        ff_ref_fdct, NO_PERM, AV_CPU_FLAG_MMX},
b250f9c6
 #if HAVE_MMX2
7160bb71
   {"MMX2",            0, ff_fdct_mmx2,       ff_ref_fdct, NO_PERM, AV_CPU_FLAG_MMX2},
   {"SSE2",            0, ff_fdct_sse2,       ff_ref_fdct, NO_PERM, AV_CPU_FLAG_SSE2},
94254fc0
 #endif
3ac35bdb
 
b250f9c6
 #if CONFIG_GPL
7160bb71
   {"LIBMPEG2-MMX",    1, ff_mmx_idct,        ff_ref_idct, MMX_PERM, AV_CPU_FLAG_MMX},
   {"LIBMPEG2-MMX2",   1, ff_mmxext_idct,     ff_ref_idct, MMX_PERM, AV_CPU_FLAG_MMX2},
b9702de5
 #endif
7160bb71
   {"SIMPLE-MMX",      1, ff_simple_idct_mmx, ff_ref_idct, MMX_SIMPLE_PERM, AV_CPU_FLAG_MMX},
   {"XVID-MMX",        1, ff_idct_xvid_mmx,   ff_ref_idct, NO_PERM, AV_CPU_FLAG_MMX},
   {"XVID-MMX2",       1, ff_idct_xvid_mmx2,  ff_ref_idct, NO_PERM, AV_CPU_FLAG_MMX2},
   {"XVID-SSE2",       1, ff_idct_xvid_sse2,  ff_ref_idct, SSE2_PERM, AV_CPU_FLAG_SSE2},
3ac35bdb
 #endif
 
b250f9c6
 #if HAVE_ALTIVEC
7160bb71
   {"altivecfdct",     0, fdct_altivec,       ff_ref_fdct, NO_PERM, AV_CPU_FLAG_ALTIVEC},
3ac35bdb
 #endif
 
b250f9c6
 #if ARCH_BFIN
0de74546
   {"BFINfdct",        0, ff_bfin_fdct,       ff_ref_fdct, NO_PERM},
   {"BFINidct",        1, ff_bfin_idct,       ff_ref_idct, NO_PERM},
3ac35bdb
 #endif
 
b250f9c6
 #if ARCH_ARM
0926c009
   {"SIMPLE-ARM",      1, ff_simple_idct_arm, ff_ref_idct, NO_PERM },
   {"INT-ARM",         1, ff_j_rev_dct_arm,   ff_ref_idct, MMX_PERM },
b250f9c6
 #if HAVE_ARMV5TE
0926c009
   {"SIMPLE-ARMV5TE",  1, ff_simple_idct_armv5te, ff_ref_idct, NO_PERM },
479044ce
 #endif
b250f9c6
 #if HAVE_ARMV6
0de74546
   {"SIMPLE-ARMV6",    1, ff_simple_idct_armv6, ff_ref_idct, MMX_PERM },
479044ce
 #endif
b250f9c6
 #if HAVE_NEON
0de74546
   {"SIMPLE-NEON",     1, ff_simple_idct_neon, ff_ref_idct, PARTTRANS_PERM },
479044ce
 #endif
a2fc0f6a
 #endif /* ARCH_ARM */
479044ce
 
2a839eeb
 #if ARCH_ALPHA
0de74546
   {"SIMPLE-ALPHA",    1, ff_simple_idct_axp,  ff_ref_idct, NO_PERM },
2a839eeb
 #endif
 
3ac35bdb
   { 0 }
 };
 
de6d9b64
 #define AANSCALE_BITS 12
 
486497e0
 uint8_t cropTbl[256 + 2 * MAX_NEG_CROP];
86748dbc
 
504ffed1
 static int64_t gettime(void)
de6d9b64
 {
     struct timeval tv;
     gettimeofday(&tv,NULL);
0c1a9eda
     return (int64_t)tv.tv_sec * 1000000 + tv.tv_usec;
de6d9b64
 }
 
 #define NB_ITS 20000
 #define NB_ITS_SPEED 50000
 
9e1586fc
 static short idct_mmx_perm[64];
 
86748dbc
 static short idct_simple_mmx_perm[64]={
bb270c08
         0x00, 0x08, 0x04, 0x09, 0x01, 0x0C, 0x05, 0x0D,
         0x10, 0x18, 0x14, 0x19, 0x11, 0x1C, 0x15, 0x1D,
         0x20, 0x28, 0x24, 0x29, 0x21, 0x2C, 0x25, 0x2D,
         0x12, 0x1A, 0x16, 0x1B, 0x13, 0x1E, 0x17, 0x1F,
         0x02, 0x0A, 0x06, 0x0B, 0x03, 0x0E, 0x07, 0x0F,
         0x30, 0x38, 0x34, 0x39, 0x31, 0x3C, 0x35, 0x3D,
         0x22, 0x2A, 0x26, 0x2B, 0x23, 0x2E, 0x27, 0x2F,
         0x32, 0x3A, 0x36, 0x3B, 0x33, 0x3E, 0x37, 0x3F,
86748dbc
 };
 
ad246860
 static const uint8_t idct_sse2_row_perm[8] = {0, 4, 1, 5, 2, 6, 3, 7};
 
504ffed1
 static void idct_mmx_init(void)
9e1586fc
 {
     int i;
 
     /* the mmx/mmxext idct uses a reordered input, so we patch scan tables */
     for (i = 0; i < 64; i++) {
bb270c08
         idct_mmx_perm[i] = (i & 0x38) | ((i & 6) >> 1) | ((i & 1) << 2);
 //        idct_simple_mmx_perm[i] = simple_block_permute_op(i);
9e1586fc
     }
 }
 
c6727809
 DECLARE_ALIGNED(16, static DCTELEM, block)[64];
 DECLARE_ALIGNED(8, static DCTELEM, block1)[64];
 DECLARE_ALIGNED(8, static DCTELEM, block_org)[64];
9e1586fc
 
aadd27cd
 static inline void mmx_emms(void)
 {
b250f9c6
 #if HAVE_MMX
7160bb71
     if (cpu_flags & AV_CPU_FLAG_MMX)
be449fca
         __asm__ volatile ("emms\n\t");
aadd27cd
 #endif
 }
 
504ffed1
 static void dct_error(const char *name, int is_idct,
9e1586fc
                void (*fdct_func)(DCTELEM *block),
007d352c
                void (*fdct_ref)(DCTELEM *block), int form, int test, const int bits)
de6d9b64
 {
     int it, i, scale;
     int err_inf, v;
0c1a9eda
     int64_t err2, ti, ti1, it1;
     int64_t sysErr[64], sysErrMax=0;
86748dbc
     int maxout=0;
     int blockSumErrMax=0, blockSumErr;
64bde197
     AVLFG prng;
007d352c
     const int vals=1<<bits;
de6d9b64
 
64bde197
     av_lfg_init(&prng, 1);
de6d9b64
 
     err_inf = 0;
     err2 = 0;
86748dbc
     for(i=0; i<64; i++) sysErr[i]=0;
de6d9b64
     for(it=0;it<NB_ITS;it++) {
86748dbc
         for(i=0;i<64;i++)
             block1[i] = 0;
         switch(test){
115329f1
         case 0:
86748dbc
             for(i=0;i<64;i++)
007d352c
                 block1[i] = (av_lfg_get(&prng) % (2*vals)) -vals;
ad324c93
             if (is_idct){
0de74546
                 ff_ref_fdct(block1);
ad324c93
 
                 for(i=0;i<64;i++)
                     block1[i]>>=3;
             }
86748dbc
         break;
         case 1:{
64bde197
             int num = av_lfg_get(&prng) % 10 + 1;
86748dbc
             for(i=0;i<num;i++)
007d352c
                 block1[av_lfg_get(&prng) % 64] = av_lfg_get(&prng) % (2*vals) -vals;
86748dbc
         }break;
         case 2:
007d352c
             block1[0] = av_lfg_get(&prng) % (16*vals) - (8*vals);
86748dbc
             block1[63]= (block1[0]&1)^1;
         break;
         }
9e1586fc
 
86748dbc
 #if 0 // simulate mismatch control
 { int sum=0;
         for(i=0;i<64;i++)
            sum+=block1[i];
 
115329f1
         if((sum&1)==0) block1[63]^=1;
86748dbc
 }
 #endif
 
         for(i=0; i<64; i++)
             block_org[i]= block1[i];
9e1586fc
 
3ac35bdb
         if (form == MMX_PERM) {
86748dbc
             for(i=0;i<64;i++)
9e1586fc
                 block[idct_mmx_perm[i]] = block1[i];
3ac35bdb
             } else if (form == MMX_SIMPLE_PERM) {
86748dbc
             for(i=0;i<64;i++)
                 block[idct_simple_mmx_perm[i]] = block1[i];
 
ad246860
         } else if (form == SSE2_PERM) {
             for(i=0; i<64; i++)
                 block[(i&0x38) | idct_sse2_row_perm[i&7]] = block1[i];
875f3125
         } else if (form == PARTTRANS_PERM) {
             for(i=0; i<64; i++)
                 block[(i&0x24) | ((i&3)<<3) | ((i>>3)&3)] = block1[i];
bb270c08
         } else {
86748dbc
             for(i=0; i<64; i++)
                 block[i]= block1[i];
9e1586fc
         }
86748dbc
 #if 0 // simulate mismatch control for tested IDCT but not the ref
 { int sum=0;
         for(i=0;i<64;i++)
            sum+=block[i];
 
115329f1
         if((sum&1)==0) block[63]^=1;
86748dbc
 }
 #endif
9e1586fc
 
de6d9b64
         fdct_func(block);
aadd27cd
         mmx_emms();
9e1586fc
 
3ac35bdb
         if (form == SCALE_PERM) {
de6d9b64
             for(i=0; i<64; i++) {
10ac3618
                 scale = 8*(1 << (AANSCALE_BITS + 11)) / ff_aanscales[i];
86748dbc
                 block[i] = (block[i] * scale /*+ (1<<(AANSCALE_BITS-1))*/) >> AANSCALE_BITS;
             }
         }
 
9e1586fc
         fdct_ref(block1);
de6d9b64
 
86748dbc
         blockSumErr=0;
de6d9b64
         for(i=0;i<64;i++) {
             v = abs(block[i] - block1[i]);
             if (v > err_inf)
                 err_inf = v;
             err2 += v * v;
bb270c08
             sysErr[i] += block[i] - block1[i];
             blockSumErr += v;
             if( abs(block[i])>maxout) maxout=abs(block[i]);
de6d9b64
         }
86748dbc
         if(blockSumErrMax < blockSumErr) blockSumErrMax= blockSumErr;
 #if 0 // print different matrix pairs
         if(blockSumErr){
             printf("\n");
             for(i=0; i<64; i++){
                 if((i&7)==0) printf("\n");
                 printf("%4d ", block_org[i]);
             }
             for(i=0; i<64; i++){
                 if((i&7)==0) printf("\n");
                 printf("%4d ", block[i] - block1[i]);
             }
         }
 #endif
     }
ae32e509
     for(i=0; i<64; i++) sysErrMax= FFMAX(sysErrMax, FFABS(sysErr[i]));
115329f1
 
86748dbc
     for(i=0; i<64; i++){
bb270c08
         if(i%8==0) printf("\n");
2029e934
         printf("%7d ", (int)sysErr[i]);
de6d9b64
     }
86748dbc
     printf("\n");
115329f1
 
86748dbc
     printf("%s %s: err_inf=%d err2=%0.8f syserr=%0.8f maxout=%d blockSumErr=%d\n",
9e1586fc
            is_idct ? "IDCT" : "DCT",
86748dbc
            name, err_inf, (double)err2 / NB_ITS / 64.0, (double)sysErrMax / NB_ITS, maxout, blockSumErrMax);
e6ff0648
 
de6d9b64
     /* speed test */
86748dbc
     for(i=0;i<64;i++)
         block1[i] = 0;
     switch(test){
115329f1
     case 0:
86748dbc
         for(i=0;i<64;i++)
007d352c
             block1[i] = av_lfg_get(&prng) % (2*vals) -vals;
ad324c93
         if (is_idct){
0de74546
             ff_ref_fdct(block1);
ad324c93
 
             for(i=0;i<64;i++)
                 block1[i]>>=3;
         }
86748dbc
     break;
     case 1:{
     case 2:
007d352c
         block1[0] = av_lfg_get(&prng) % (2*vals) -vals;
         block1[1] = av_lfg_get(&prng) % (2*vals) -vals;
         block1[2] = av_lfg_get(&prng) % (2*vals) -vals;
         block1[3] = av_lfg_get(&prng) % (2*vals) -vals;
86748dbc
     }break;
     }
de6d9b64
 
3ac35bdb
     if (form == MMX_PERM) {
86748dbc
         for(i=0;i<64;i++)
9e1586fc
             block[idct_mmx_perm[i]] = block1[i];
3ac35bdb
     } else if(form == MMX_SIMPLE_PERM) {
86748dbc
         for(i=0;i<64;i++)
             block[idct_simple_mmx_perm[i]] = block1[i];
     } else {
         for(i=0; i<64; i++)
             block[i]= block1[i];
9e1586fc
     }
 
de6d9b64
     ti = gettime();
     it1 = 0;
     do {
         for(it=0;it<NB_ITS_SPEED;it++) {
86748dbc
             for(i=0; i<64; i++)
                 block[i]= block1[i];
 //            memcpy(block, block1, sizeof(DCTELEM) * 64);
755bfeab
 // do not memcpy especially not fastmemcpy because it does movntq !!!
de6d9b64
             fdct_func(block);
         }
         it1 += NB_ITS_SPEED;
         ti1 = gettime() - ti;
     } while (ti1 < 1000000);
aadd27cd
     mmx_emms();
de6d9b64
 
86748dbc
     printf("%s %s: %0.1f kdct/s\n",
9e1586fc
            is_idct ? "IDCT" : "DCT",
de6d9b64
            name, (double)it1 * 1000.0 / (double)ti1);
 }
 
c6727809
 DECLARE_ALIGNED(8, static uint8_t, img_dest)[64];
 DECLARE_ALIGNED(8, static uint8_t, img_dest1)[64];
a46a3ce4
 
504ffed1
 static void idct248_ref(uint8_t *dest, int linesize, int16_t *block)
a46a3ce4
 {
     static int init;
     static double c8[8][8];
     static double c4[4][4];
     double block1[64], block2[64], block3[64];
     double s, sum, v;
     int i, j, k;
 
     if (!init) {
         init = 1;
 
         for(i=0;i<8;i++) {
             sum = 0;
             for(j=0;j<8;j++) {
                 s = (i==0) ? sqrt(1.0/8.0) : sqrt(1.0/4.0);
                 c8[i][j] = s * cos(M_PI * i * (j + 0.5) / 8.0);
                 sum += c8[i][j] * c8[i][j];
             }
         }
115329f1
 
a46a3ce4
         for(i=0;i<4;i++) {
             sum = 0;
             for(j=0;j<4;j++) {
                 s = (i==0) ? sqrt(1.0/4.0) : sqrt(1.0/2.0);
                 c4[i][j] = s * cos(M_PI * i * (j + 0.5) / 4.0);
                 sum += c4[i][j] * c4[i][j];
             }
         }
     }
 
     /* butterfly */
652f0197
     s = 0.5 * sqrt(2.0);
a46a3ce4
     for(i=0;i<4;i++) {
         for(j=0;j<8;j++) {
652f0197
             block1[8*(2*i)+j] = (block[8*(2*i)+j] + block[8*(2*i+1)+j]) * s;
             block1[8*(2*i+1)+j] = (block[8*(2*i)+j] - block[8*(2*i+1)+j]) * s;
a46a3ce4
         }
     }
 
     /* idct8 on lines */
     for(i=0;i<8;i++) {
         for(j=0;j<8;j++) {
             sum = 0;
             for(k=0;k<8;k++)
                 sum += c8[k][j] * block1[8*i+k];
             block2[8*i+j] = sum;
         }
     }
 
     /* idct4 */
     for(i=0;i<8;i++) {
         for(j=0;j<4;j++) {
             /* top */
             sum = 0;
             for(k=0;k<4;k++)
                 sum += c4[k][j] * block2[8*(2*k)+i];
             block3[8*(2*j)+i] = sum;
 
             /* bottom */
             sum = 0;
             for(k=0;k<4;k++)
                 sum += c4[k][j] * block2[8*(2*k+1)+i];
             block3[8*(2*j+1)+i] = sum;
         }
     }
 
     /* clamp and store the result */
     for(i=0;i<8;i++) {
         for(j=0;j<8;j++) {
652f0197
             v = block3[8*i+j];
a46a3ce4
             if (v < 0)
                 v = 0;
             else if (v > 255)
                 v = 255;
             dest[i * linesize + j] = (int)rint(v);
         }
     }
 }
 
504ffed1
 static void idct248_error(const char *name,
0c1a9eda
                     void (*idct248_put)(uint8_t *dest, int line_size, int16_t *block))
a46a3ce4
 {
     int it, i, it1, ti, ti1, err_max, v;
 
64bde197
     AVLFG prng;
294eaa26
 
64bde197
     av_lfg_init(&prng, 1);
115329f1
 
a46a3ce4
     /* just one test to see if code is correct (precision is less
        important here) */
     err_max = 0;
     for(it=0;it<NB_ITS;it++) {
115329f1
 
652f0197
         /* XXX: use forward transform to generate values */
         for(i=0;i<64;i++)
64bde197
             block1[i] = av_lfg_get(&prng) % 256 - 128;
652f0197
         block1[0] += 1024;
 
a46a3ce4
         for(i=0; i<64; i++)
             block[i]= block1[i];
         idct248_ref(img_dest1, 8, block);
115329f1
 
652f0197
         for(i=0; i<64; i++)
             block[i]= block1[i];
         idct248_put(img_dest, 8, block);
115329f1
 
652f0197
         for(i=0;i<64;i++) {
             v = abs((int)img_dest[i] - (int)img_dest1[i]);
             if (v == 255)
                 printf("%d %d\n", img_dest[i], img_dest1[i]);
             if (v > err_max)
                 err_max = v;
         }
a46a3ce4
 #if 0
         printf("ref=\n");
         for(i=0;i<8;i++) {
             int j;
             for(j=0;j<8;j++) {
                 printf(" %3d", img_dest1[i*8+j]);
             }
             printf("\n");
         }
115329f1
 
a46a3ce4
         printf("out=\n");
         for(i=0;i<8;i++) {
             int j;
             for(j=0;j<8;j++) {
                 printf(" %3d", img_dest[i*8+j]);
             }
             printf("\n");
         }
 #endif
     }
     printf("%s %s: err_inf=%d\n",
            1 ? "IDCT248" : "DCT248",
            name, err_max);
 
     ti = gettime();
     it1 = 0;
     do {
         for(it=0;it<NB_ITS_SPEED;it++) {
             for(i=0; i<64; i++)
                 block[i]= block1[i];
 //            memcpy(block, block1, sizeof(DCTELEM) * 64);
755bfeab
 // do not memcpy especially not fastmemcpy because it does movntq !!!
a46a3ce4
             idct248_put(img_dest, 8, block);
         }
         it1 += NB_ITS_SPEED;
         ti1 = gettime() - ti;
     } while (ti1 < 1000000);
aadd27cd
     mmx_emms();
a46a3ce4
 
     printf("%s %s: %0.1f kdct/s\n",
            1 ? "IDCT248" : "DCT248",
            name, (double)it1 * 1000.0 / (double)ti1);
 }
 
504ffed1
 static void help(void)
9e1586fc
 {
86748dbc
     printf("dct-test [-i] [<test-number>]\n"
            "test-number 0 -> test with random matrixes\n"
            "            1 -> test with random sparse matrixes\n"
            "            2 -> do 3. test from mpeg4 std\n"
a46a3ce4
            "-i          test IDCT implementations\n"
            "-4          test IDCT248 implementations\n");
9e1586fc
 }
 
de6d9b64
 int main(int argc, char **argv)
 {
a46a3ce4
     int test_idct = 0, test_248_dct = 0;
86748dbc
     int c,i;
     int test=1;
007d352c
     int bits=8;
c6c98d08
     cpu_flags = av_get_cpu_flags();
9e1586fc
 
0de74546
     ff_ref_dct_init();
9e1586fc
     idct_mmx_init();
f67a10cd
 
486497e0
     for(i=0;i<256;i++) cropTbl[i + MAX_NEG_CROP] = i;
86748dbc
     for(i=0;i<MAX_NEG_CROP;i++) {
486497e0
         cropTbl[i] = 0;
         cropTbl[i + MAX_NEG_CROP + 256] = 255;
86748dbc
     }
115329f1
 
9e1586fc
     for(;;) {
a46a3ce4
         c = getopt(argc, argv, "ih4");
9e1586fc
         if (c == -1)
             break;
         switch(c) {
         case 'i':
             test_idct = 1;
             break;
a46a3ce4
         case '4':
             test_248_dct = 1;
             break;
86748dbc
         default :
9e1586fc
         case 'h':
             help();
c6bdc908
             return 0;
9e1586fc
         }
     }
115329f1
 
86748dbc
     if(optind <argc) test= atoi(argv[optind]);
007d352c
     if(optind+1 < argc) bits= atoi(argv[optind+1]);
115329f1
 
9e1586fc
     printf("ffmpeg DCT/IDCT test\n");
 
a46a3ce4
     if (test_248_dct) {
59e6f60a
         idct248_error("SIMPLE-C", ff_simple_idct248_put);
9e1586fc
     } else {
3ac35bdb
       for (i=0;algos[i].name;i++)
dafe8824
         if (algos[i].is_idct == test_idct && !(~cpu_flags & algos[i].mm_support)) {
007d352c
           dct_error (algos[i].name, algos[i].is_idct, algos[i].func, algos[i].ref, algos[i].format, test, bits);
a46a3ce4
         }
9e1586fc
     }
de6d9b64
     return 0;
 }