cosmetics: Remove period after copyright statement non-sentence.
[libav.git] / libavcodec / dct-test.c
CommitLineData
04d7f601
DB
1/*
2 * (c) 2001 Fabrice Bellard
3ac35bdb 3 * 2007 Marc Hoffman <marc.hoffman@analog.com>
04d7f601 4 *
b78e7197
DB
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
04d7f601
DB
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
b78e7197 10 * version 2.1 of the License, or (at your option) any later version.
04d7f601 11 *
b78e7197 12 * FFmpeg is distributed in the hope that it will be useful,
04d7f601
DB
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
b78e7197 18 * License along with FFmpeg; if not, write to the Free Software
04d7f601
DB
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
983e3246 22/**
bad5537e 23 * @file libavcodec/dct-test.c
115329f1 24 * DCT test. (c) 2001 Fabrice Bellard.
983e3246
MN
25 * Started from sample code by Juan J. Sierralta P.
26 */
27
de6d9b64
FB
28#include <stdlib.h>
29#include <stdio.h>
30#include <string.h>
31#include <sys/time.h>
32#include <unistd.h>
12807c8d 33#include <math.h>
de6d9b64 34
ae32e509 35#include "libavutil/common.h"
de6d9b64 36
86748dbc 37#include "simple_idct.h"
10ac3618 38#include "aandcttab.h"
65e4c8c9 39#include "faandct.h"
6f08c541 40#include "faanidct.h"
a6493a8f 41#include "x86/idct_xvid.h"
9e1586fc 42
434df899 43#undef printf
cc61f96f 44#undef random
434df899
MN
45
46void *fast_memcpy(void *a, const void *b, size_t c){return memcpy(a,b,c);};
47
9e1586fc 48/* reference fdct/idct */
9686df2b
DB
49void fdct(DCTELEM *block);
50void idct(DCTELEM *block);
dc8a7c93 51void init_fdct(void);
de6d9b64 52
9686df2b
DB
53void ff_mmx_idct(DCTELEM *data);
54void ff_mmxext_idct(DCTELEM *data);
9e1586fc 55
9686df2b 56void odivx_idct_c(short *block);
86748dbc 57
3ac35bdb 58// BFIN
9686df2b
DB
59void ff_bfin_idct(DCTELEM *block);
60void ff_bfin_fdct(DCTELEM *block);
3ac35bdb
MH
61
62// ALTIVEC
9686df2b
DB
63void fdct_altivec(DCTELEM *block);
64//void idct_altivec(DCTELEM *block);?? no routine
3ac35bdb 65
479044ce
MR
66// ARM
67void j_rev_dct_ARM(DCTELEM *data);
68void simple_idct_ARM(DCTELEM *data);
69void simple_idct_armv5te(DCTELEM *data);
70void ff_simple_idct_armv6(DCTELEM *data);
71void ff_simple_idct_neon(DCTELEM *data);
3ac35bdb 72
2a839eeb
MR
73void ff_simple_idct_axp(DCTELEM *data);
74
3ac35bdb 75struct algo {
f5b67781 76 const char *name;
3ac35bdb
MH
77 enum { FDCT, IDCT } is_idct;
78 void (* func) (DCTELEM *block);
79 void (* ref) (DCTELEM *block);
875f3125 80 enum formattag { NO_PERM,MMX_PERM, MMX_SIMPLE_PERM, SCALE_PERM, SSE2_PERM, PARTTRANS_PERM } format;
3794b928 81 int mm_support;
3ac35bdb
MH
82};
83
84#ifndef FAAN_POSTSCALE
85#define FAAN_SCALE SCALE_PERM
86#else
87#define FAAN_SCALE NO_PERM
88#endif
89
aadd27cd
MN
90static int cpu_flags;
91
3ac35bdb 92struct algo algos[] = {
1a7ee380
AS
93 {"REF-DBL", 0, fdct, fdct, NO_PERM},
94 {"FAAN", 0, ff_faandct, fdct, FAAN_SCALE},
95 {"FAANI", 1, ff_faanidct, idct, NO_PERM},
96 {"IJG-AAN-INT", 0, fdct_ifast, fdct, SCALE_PERM},
97 {"IJG-LLM-INT", 0, ff_jpeg_fdct_islow, fdct, NO_PERM},
98 {"REF-DBL", 1, idct, idct, NO_PERM},
99 {"INT", 1, j_rev_dct, idct, MMX_PERM},
100 {"SIMPLE-C", 1, ff_simple_idct, idct, NO_PERM},
3ac35bdb 101
b250f9c6 102#if HAVE_MMX
82d1605f 103 {"MMX", 0, ff_fdct_mmx, fdct, NO_PERM, FF_MM_MMX},
b250f9c6 104#if HAVE_MMX2
82d1605f 105 {"MMX2", 0, ff_fdct_mmx2, fdct, NO_PERM, FF_MM_MMXEXT},
83534418 106 {"SSE2", 0, ff_fdct_sse2, fdct, NO_PERM, FF_MM_SSE2},
94254fc0 107#endif
3ac35bdb 108
b250f9c6 109#if CONFIG_GPL
82d1605f
DM
110 {"LIBMPEG2-MMX", 1, ff_mmx_idct, idct, MMX_PERM, FF_MM_MMX},
111 {"LIBMPEG2-MMXEXT", 1, ff_mmxext_idct, idct, MMX_PERM, FF_MM_MMXEXT},
b9702de5 112#endif
82d1605f
DM
113 {"SIMPLE-MMX", 1, ff_simple_idct_mmx, idct, MMX_SIMPLE_PERM, FF_MM_MMX},
114 {"XVID-MMX", 1, ff_idct_xvid_mmx, idct, NO_PERM, FF_MM_MMX},
115 {"XVID-MMX2", 1, ff_idct_xvid_mmx2, idct, NO_PERM, FF_MM_MMXEXT},
116 {"XVID-SSE2", 1, ff_idct_xvid_sse2, idct, SSE2_PERM, FF_MM_SSE2},
3ac35bdb
MH
117#endif
118
b250f9c6 119#if HAVE_ALTIVEC
82d1605f 120 {"altivecfdct", 0, fdct_altivec, fdct, NO_PERM, FF_MM_ALTIVEC},
3ac35bdb
MH
121#endif
122
b250f9c6 123#if ARCH_BFIN
1a7ee380
AS
124 {"BFINfdct", 0, ff_bfin_fdct, fdct, NO_PERM},
125 {"BFINidct", 1, ff_bfin_idct, idct, NO_PERM},
3ac35bdb
MH
126#endif
127
b250f9c6 128#if ARCH_ARM
479044ce
MR
129 {"SIMPLE-ARM", 1, simple_idct_ARM, idct, NO_PERM },
130 {"INT-ARM", 1, j_rev_dct_ARM, idct, MMX_PERM },
b250f9c6 131#if HAVE_ARMV5TE
479044ce
MR
132 {"SIMPLE-ARMV5TE", 1, simple_idct_armv5te, idct, NO_PERM },
133#endif
b250f9c6 134#if HAVE_ARMV6
479044ce
MR
135 {"SIMPLE-ARMV6", 1, ff_simple_idct_armv6, idct, MMX_PERM },
136#endif
b250f9c6 137#if HAVE_NEON
479044ce
MR
138 {"SIMPLE-NEON", 1, ff_simple_idct_neon, idct, PARTTRANS_PERM },
139#endif
a2fc0f6a 140#endif /* ARCH_ARM */
479044ce 141
2a839eeb
MR
142#if ARCH_ALPHA
143 {"SIMPLE-ALPHA", 1, ff_simple_idct_axp, idct, NO_PERM },
144#endif
145
3ac35bdb
MH
146 { 0 }
147};
148
de6d9b64 149#define AANSCALE_BITS 12
de6d9b64 150
486497e0 151uint8_t cropTbl[256 + 2 * MAX_NEG_CROP];
86748dbc 152
0c1a9eda 153int64_t gettime(void)
de6d9b64
FB
154{
155 struct timeval tv;
156 gettimeofday(&tv,NULL);
0c1a9eda 157 return (int64_t)tv.tv_sec * 1000000 + tv.tv_usec;
de6d9b64
FB
158}
159
160#define NB_ITS 20000
161#define NB_ITS_SPEED 50000
162
9e1586fc
FB
163static short idct_mmx_perm[64];
164
86748dbc 165static short idct_simple_mmx_perm[64]={
bb270c08
DB
166 0x00, 0x08, 0x04, 0x09, 0x01, 0x0C, 0x05, 0x0D,
167 0x10, 0x18, 0x14, 0x19, 0x11, 0x1C, 0x15, 0x1D,
168 0x20, 0x28, 0x24, 0x29, 0x21, 0x2C, 0x25, 0x2D,
169 0x12, 0x1A, 0x16, 0x1B, 0x13, 0x1E, 0x17, 0x1F,
170 0x02, 0x0A, 0x06, 0x0B, 0x03, 0x0E, 0x07, 0x0F,
171 0x30, 0x38, 0x34, 0x39, 0x31, 0x3C, 0x35, 0x3D,
172 0x22, 0x2A, 0x26, 0x2B, 0x23, 0x2E, 0x27, 0x2F,
173 0x32, 0x3A, 0x36, 0x3B, 0x33, 0x3E, 0x37, 0x3F,
86748dbc
MN
174};
175
ad246860
AS
176static const uint8_t idct_sse2_row_perm[8] = {0, 4, 1, 5, 2, 6, 3, 7};
177
9e1586fc
FB
178void idct_mmx_init(void)
179{
180 int i;
181
182 /* the mmx/mmxext idct uses a reordered input, so we patch scan tables */
183 for (i = 0; i < 64; i++) {
bb270c08
DB
184 idct_mmx_perm[i] = (i & 0x38) | ((i & 6) >> 1) | ((i & 1) << 2);
185// idct_simple_mmx_perm[i] = simple_block_permute_op(i);
9e1586fc
FB
186 }
187}
188
55727a83 189static DCTELEM block[64] __attribute__ ((aligned (16)));
9e1586fc 190static DCTELEM block1[64] __attribute__ ((aligned (8)));
86748dbc 191static DCTELEM block_org[64] __attribute__ ((aligned (8)));
9e1586fc 192
aadd27cd
MN
193static inline void mmx_emms(void)
194{
b250f9c6 195#if HAVE_MMX
82d1605f 196 if (cpu_flags & FF_MM_MMX)
be449fca 197 __asm__ volatile ("emms\n\t");
aadd27cd
MN
198#endif
199}
200
9e1586fc
FB
201void dct_error(const char *name, int is_idct,
202 void (*fdct_func)(DCTELEM *block),
3ac35bdb 203 void (*fdct_ref)(DCTELEM *block), int form, int test)
de6d9b64
FB
204{
205 int it, i, scale;
de6d9b64 206 int err_inf, v;
0c1a9eda
ZK
207 int64_t err2, ti, ti1, it1;
208 int64_t sysErr[64], sysErrMax=0;
86748dbc 209 int maxout=0;
86748dbc 210 int blockSumErrMax=0, blockSumErr;
de6d9b64
FB
211
212 srandom(0);
213
214 err_inf = 0;
215 err2 = 0;
86748dbc 216 for(i=0; i<64; i++) sysErr[i]=0;
de6d9b64 217 for(it=0;it<NB_ITS;it++) {
86748dbc
MN
218 for(i=0;i<64;i++)
219 block1[i] = 0;
220 switch(test){
115329f1 221 case 0:
86748dbc
MN
222 for(i=0;i<64;i++)
223 block1[i] = (random() % 512) -256;
ad324c93 224 if (is_idct){
86748dbc 225 fdct(block1);
ad324c93
MN
226
227 for(i=0;i<64;i++)
228 block1[i]>>=3;
229 }
86748dbc
MN
230 break;
231 case 1:{
232 int num= (random()%10)+1;
233 for(i=0;i<num;i++)
234 block1[random()%64] = (random() % 512) -256;
235 }break;
236 case 2:
237 block1[0]= (random()%4096)-2048;
238 block1[63]= (block1[0]&1)^1;
239 break;
240 }
9e1586fc 241
86748dbc
MN
242#if 0 // simulate mismatch control
243{ int sum=0;
244 for(i=0;i<64;i++)
245 sum+=block1[i];
246
115329f1 247 if((sum&1)==0) block1[63]^=1;
86748dbc
MN
248}
249#endif
250
251 for(i=0; i<64; i++)
252 block_org[i]= block1[i];
9e1586fc 253
3ac35bdb 254 if (form == MMX_PERM) {
86748dbc 255 for(i=0;i<64;i++)
9e1586fc 256 block[idct_mmx_perm[i]] = block1[i];
3ac35bdb 257 } else if (form == MMX_SIMPLE_PERM) {
86748dbc
MN
258 for(i=0;i<64;i++)
259 block[idct_simple_mmx_perm[i]] = block1[i];
260
ad246860
AS
261 } else if (form == SSE2_PERM) {
262 for(i=0; i<64; i++)
263 block[(i&0x38) | idct_sse2_row_perm[i&7]] = block1[i];
875f3125
MR
264 } else if (form == PARTTRANS_PERM) {
265 for(i=0; i<64; i++)
266 block[(i&0x24) | ((i&3)<<3) | ((i>>3)&3)] = block1[i];
bb270c08 267 } else {
86748dbc
MN
268 for(i=0; i<64; i++)
269 block[i]= block1[i];
9e1586fc 270 }
86748dbc
MN
271#if 0 // simulate mismatch control for tested IDCT but not the ref
272{ int sum=0;
273 for(i=0;i<64;i++)
274 sum+=block[i];
275
115329f1 276 if((sum&1)==0) block[63]^=1;
86748dbc
MN
277}
278#endif
9e1586fc 279
de6d9b64 280 fdct_func(block);
aadd27cd 281 mmx_emms();
9e1586fc 282
3ac35bdb 283 if (form == SCALE_PERM) {
de6d9b64 284 for(i=0; i<64; i++) {
10ac3618 285 scale = 8*(1 << (AANSCALE_BITS + 11)) / ff_aanscales[i];
86748dbc
MN
286 block[i] = (block[i] * scale /*+ (1<<(AANSCALE_BITS-1))*/) >> AANSCALE_BITS;
287 }
288 }
289
9e1586fc 290 fdct_ref(block1);
de6d9b64 291
86748dbc 292 blockSumErr=0;
de6d9b64
FB
293 for(i=0;i<64;i++) {
294 v = abs(block[i] - block1[i]);
295 if (v > err_inf)
296 err_inf = v;
297 err2 += v * v;
bb270c08
DB
298 sysErr[i] += block[i] - block1[i];
299 blockSumErr += v;
300 if( abs(block[i])>maxout) maxout=abs(block[i]);
de6d9b64 301 }
86748dbc
MN
302 if(blockSumErrMax < blockSumErr) blockSumErrMax= blockSumErr;
303#if 0 // print different matrix pairs
304 if(blockSumErr){
305 printf("\n");
306 for(i=0; i<64; i++){
307 if((i&7)==0) printf("\n");
308 printf("%4d ", block_org[i]);
309 }
310 for(i=0; i<64; i++){
311 if((i&7)==0) printf("\n");
312 printf("%4d ", block[i] - block1[i]);
313 }
314 }
315#endif
316 }
ae32e509 317 for(i=0; i<64; i++) sysErrMax= FFMAX(sysErrMax, FFABS(sysErr[i]));
115329f1 318
86748dbc
MN
319#if 1 // dump systematic errors
320 for(i=0; i<64; i++){
bb270c08 321 if(i%8==0) printf("\n");
86748dbc 322 printf("%5d ", (int)sysErr[i]);
de6d9b64 323 }
86748dbc
MN
324 printf("\n");
325#endif
115329f1 326
86748dbc 327 printf("%s %s: err_inf=%d err2=%0.8f syserr=%0.8f maxout=%d blockSumErr=%d\n",
9e1586fc 328 is_idct ? "IDCT" : "DCT",
86748dbc
MN
329 name, err_inf, (double)err2 / NB_ITS / 64.0, (double)sysErrMax / NB_ITS, maxout, blockSumErrMax);
330#if 1 //Speed test
de6d9b64 331 /* speed test */
86748dbc
MN
332 for(i=0;i<64;i++)
333 block1[i] = 0;
334 switch(test){
115329f1 335 case 0:
86748dbc
MN
336 for(i=0;i<64;i++)
337 block1[i] = (random() % 512) -256;
ad324c93 338 if (is_idct){
86748dbc 339 fdct(block1);
ad324c93
MN
340
341 for(i=0;i<64;i++)
342 block1[i]>>=3;
343 }
86748dbc
MN
344 break;
345 case 1:{
346 case 2:
347 block1[0] = (random() % 512) -256;
348 block1[1] = (random() % 512) -256;
349 block1[2] = (random() % 512) -256;
350 block1[3] = (random() % 512) -256;
351 }break;
352 }
de6d9b64 353
3ac35bdb 354 if (form == MMX_PERM) {
86748dbc 355 for(i=0;i<64;i++)
9e1586fc 356 block[idct_mmx_perm[i]] = block1[i];
3ac35bdb 357 } else if(form == MMX_SIMPLE_PERM) {
86748dbc
MN
358 for(i=0;i<64;i++)
359 block[idct_simple_mmx_perm[i]] = block1[i];
360 } else {
361 for(i=0; i<64; i++)
362 block[i]= block1[i];
9e1586fc
FB
363 }
364
de6d9b64
FB
365 ti = gettime();
366 it1 = 0;
367 do {
368 for(it=0;it<NB_ITS_SPEED;it++) {
86748dbc
MN
369 for(i=0; i<64; i++)
370 block[i]= block1[i];
371// memcpy(block, block1, sizeof(DCTELEM) * 64);
755bfeab 372// do not memcpy especially not fastmemcpy because it does movntq !!!
de6d9b64
FB
373 fdct_func(block);
374 }
375 it1 += NB_ITS_SPEED;
376 ti1 = gettime() - ti;
377 } while (ti1 < 1000000);
aadd27cd 378 mmx_emms();
de6d9b64 379
86748dbc 380 printf("%s %s: %0.1f kdct/s\n",
9e1586fc 381 is_idct ? "IDCT" : "DCT",
de6d9b64 382 name, (double)it1 * 1000.0 / (double)ti1);
86748dbc 383#endif
de6d9b64
FB
384}
385
0c1a9eda
ZK
386static uint8_t img_dest[64] __attribute__ ((aligned (8)));
387static uint8_t img_dest1[64] __attribute__ ((aligned (8)));
a46a3ce4 388
0c1a9eda 389void idct248_ref(uint8_t *dest, int linesize, int16_t *block)
a46a3ce4
FB
390{
391 static int init;
392 static double c8[8][8];
393 static double c4[4][4];
394 double block1[64], block2[64], block3[64];
395 double s, sum, v;
396 int i, j, k;
397
398 if (!init) {
399 init = 1;
400
401 for(i=0;i<8;i++) {
402 sum = 0;
403 for(j=0;j<8;j++) {
404 s = (i==0) ? sqrt(1.0/8.0) : sqrt(1.0/4.0);
405 c8[i][j] = s * cos(M_PI * i * (j + 0.5) / 8.0);
406 sum += c8[i][j] * c8[i][j];
407 }
408 }
115329f1 409
a46a3ce4
FB
410 for(i=0;i<4;i++) {
411 sum = 0;
412 for(j=0;j<4;j++) {
413 s = (i==0) ? sqrt(1.0/4.0) : sqrt(1.0/2.0);
414 c4[i][j] = s * cos(M_PI * i * (j + 0.5) / 4.0);
415 sum += c4[i][j] * c4[i][j];
416 }
417 }
418 }
419
420 /* butterfly */
652f0197 421 s = 0.5 * sqrt(2.0);
a46a3ce4
FB
422 for(i=0;i<4;i++) {
423 for(j=0;j<8;j++) {
652f0197
FB
424 block1[8*(2*i)+j] = (block[8*(2*i)+j] + block[8*(2*i+1)+j]) * s;
425 block1[8*(2*i+1)+j] = (block[8*(2*i)+j] - block[8*(2*i+1)+j]) * s;
a46a3ce4
FB
426 }
427 }
428
429 /* idct8 on lines */
430 for(i=0;i<8;i++) {
431 for(j=0;j<8;j++) {
432 sum = 0;
433 for(k=0;k<8;k++)
434 sum += c8[k][j] * block1[8*i+k];
435 block2[8*i+j] = sum;
436 }
437 }
438
439 /* idct4 */
440 for(i=0;i<8;i++) {
441 for(j=0;j<4;j++) {
442 /* top */
443 sum = 0;
444 for(k=0;k<4;k++)
445 sum += c4[k][j] * block2[8*(2*k)+i];
446 block3[8*(2*j)+i] = sum;
447
448 /* bottom */
449 sum = 0;
450 for(k=0;k<4;k++)
451 sum += c4[k][j] * block2[8*(2*k+1)+i];
452 block3[8*(2*j+1)+i] = sum;
453 }
454 }
455
456 /* clamp and store the result */
457 for(i=0;i<8;i++) {
458 for(j=0;j<8;j++) {
652f0197 459 v = block3[8*i+j];
a46a3ce4
FB
460 if (v < 0)
461 v = 0;
462 else if (v > 255)
463 v = 255;
464 dest[i * linesize + j] = (int)rint(v);
465 }
466 }
467}
468
115329f1 469void idct248_error(const char *name,
0c1a9eda 470 void (*idct248_put)(uint8_t *dest, int line_size, int16_t *block))
a46a3ce4
FB
471{
472 int it, i, it1, ti, ti1, err_max, v;
473
474 srandom(0);
115329f1 475
a46a3ce4
FB
476 /* just one test to see if code is correct (precision is less
477 important here) */
478 err_max = 0;
479 for(it=0;it<NB_ITS;it++) {
115329f1 480
652f0197
FB
481 /* XXX: use forward transform to generate values */
482 for(i=0;i<64;i++)
483 block1[i] = (random() % 256) - 128;
484 block1[0] += 1024;
485
a46a3ce4
FB
486 for(i=0; i<64; i++)
487 block[i]= block1[i];
488 idct248_ref(img_dest1, 8, block);
115329f1 489
652f0197
FB
490 for(i=0; i<64; i++)
491 block[i]= block1[i];
492 idct248_put(img_dest, 8, block);
115329f1 493
652f0197
FB
494 for(i=0;i<64;i++) {
495 v = abs((int)img_dest[i] - (int)img_dest1[i]);
496 if (v == 255)
497 printf("%d %d\n", img_dest[i], img_dest1[i]);
498 if (v > err_max)
499 err_max = v;
500 }
a46a3ce4
FB
501#if 0
502 printf("ref=\n");
503 for(i=0;i<8;i++) {
504 int j;
505 for(j=0;j<8;j++) {
506 printf(" %3d", img_dest1[i*8+j]);
507 }
508 printf("\n");
509 }
115329f1 510
a46a3ce4
FB
511 printf("out=\n");
512 for(i=0;i<8;i++) {
513 int j;
514 for(j=0;j<8;j++) {
515 printf(" %3d", img_dest[i*8+j]);
516 }
517 printf("\n");
518 }
519#endif
a46a3ce4
FB
520 }
521 printf("%s %s: err_inf=%d\n",
522 1 ? "IDCT248" : "DCT248",
523 name, err_max);
524
525 ti = gettime();
526 it1 = 0;
527 do {
528 for(it=0;it<NB_ITS_SPEED;it++) {
529 for(i=0; i<64; i++)
530 block[i]= block1[i];
531// memcpy(block, block1, sizeof(DCTELEM) * 64);
755bfeab 532// do not memcpy especially not fastmemcpy because it does movntq !!!
a46a3ce4
FB
533 idct248_put(img_dest, 8, block);
534 }
535 it1 += NB_ITS_SPEED;
536 ti1 = gettime() - ti;
537 } while (ti1 < 1000000);
aadd27cd 538 mmx_emms();
a46a3ce4
FB
539
540 printf("%s %s: %0.1f kdct/s\n",
541 1 ? "IDCT248" : "DCT248",
542 name, (double)it1 * 1000.0 / (double)ti1);
543}
544
9e1586fc
FB
545void help(void)
546{
86748dbc
MN
547 printf("dct-test [-i] [<test-number>]\n"
548 "test-number 0 -> test with random matrixes\n"
549 " 1 -> test with random sparse matrixes\n"
550 " 2 -> do 3. test from mpeg4 std\n"
a46a3ce4
FB
551 "-i test IDCT implementations\n"
552 "-4 test IDCT248 implementations\n");
9e1586fc
FB
553}
554
de6d9b64
FB
555int main(int argc, char **argv)
556{
a46a3ce4 557 int test_idct = 0, test_248_dct = 0;
86748dbc
MN
558 int c,i;
559 int test=1;
aadd27cd 560 cpu_flags = mm_support();
9e1586fc 561
de6d9b64 562 init_fdct();
9e1586fc 563 idct_mmx_init();
f67a10cd 564
486497e0 565 for(i=0;i<256;i++) cropTbl[i + MAX_NEG_CROP] = i;
86748dbc 566 for(i=0;i<MAX_NEG_CROP;i++) {
486497e0
MR
567 cropTbl[i] = 0;
568 cropTbl[i + MAX_NEG_CROP + 256] = 255;
86748dbc 569 }
115329f1 570
9e1586fc 571 for(;;) {
a46a3ce4 572 c = getopt(argc, argv, "ih4");
9e1586fc
FB
573 if (c == -1)
574 break;
575 switch(c) {
576 case 'i':
577 test_idct = 1;
578 break;
a46a3ce4
FB
579 case '4':
580 test_248_dct = 1;
581 break;
86748dbc 582 default :
9e1586fc
FB
583 case 'h':
584 help();
c6bdc908 585 return 0;
9e1586fc
FB
586 }
587 }
115329f1 588
86748dbc 589 if(optind <argc) test= atoi(argv[optind]);
115329f1 590
9e1586fc
FB
591 printf("ffmpeg DCT/IDCT test\n");
592
a46a3ce4 593 if (test_248_dct) {
59e6f60a 594 idct248_error("SIMPLE-C", ff_simple_idct248_put);
9e1586fc 595 } else {
3ac35bdb 596 for (i=0;algos[i].name;i++)
dafe8824 597 if (algos[i].is_idct == test_idct && !(~cpu_flags & algos[i].mm_support)) {
3ac35bdb 598 dct_error (algos[i].name, algos[i].is_idct, algos[i].func, algos[i].ref, algos[i].format, test);
a46a3ce4 599 }
9e1586fc 600 }
de6d9b64
FB
601 return 0;
602}