Improve Sofdec file detection
[libav.git] / tests / tiny_psnr.c
CommitLineData
67cbe681
MN
1/*
2 * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
3 *
244e1e64
DB
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
67cbe681
MN
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
244e1e64 9 * version 2.1 of the License, or (at your option) any later version.
67cbe681 10 *
244e1e64 11 * FFmpeg is distributed in the hope that it will be useful,
67cbe681
MN
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
244e1e64 17 * License along with FFmpeg; if not, write to the Free Software
5509bffa 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
67cbe681
MN
19 */
20
21#include <stdio.h>
ba96e97f 22#include <stdlib.h>
67cbe681 23#include <inttypes.h>
9e2a16e1 24#include <assert.h>
67cbe681
MN
25
26#define F 100
27#define SIZE 2048
28
0c90161f 29uint64_t exp16_table[21]={
9e2a16e1
MN
30 65537,
31 65538,
32 65540,
33 65544,
34 65552,
35 65568,
36 65600,
37 65664,
38 65793,
39 66050,
40 66568,
41 67616,
42 69763,
43 74262,
44 84150,
45 108051,
46 178145,
47 484249,
48 3578144,
49 195360063,
0c90161f 50 582360139072LL,
9e2a16e1 51};
2d2fe557
DB
52#if 1
53// 16.16 fixpoint exp()
54static unsigned int exp16(unsigned int a){
55 int i;
56 int out= 1<<16;
57
58 for(i=19;i>=0;i--){
59 if(a&(1<<i))
60 out= (out*exp16_table[i] + (1<<15))>>16;
61 }
9e2a16e1 62
2d2fe557
DB
63 return out;
64}
9e2a16e1 65// 16.16 fixpoint log()
0c90161f 66static int64_t log16(uint64_t a){
9e2a16e1
MN
67 int i;
68 int out=0;
0c90161f
MN
69
70 if(a < 1<<16)
71 return -log16((1LL<<32) / a);
9e2a16e1 72 a<<=16;
115329f1 73
0c90161f 74 for(i=20;i>=0;i--){
8176bd1a
MN
75 int64_t b= exp16_table[i];
76 if(a<(b<<16)) continue;
9e2a16e1 77 out |= 1<<i;
8176bd1a 78 a = ((a/b)<<16) + (((a%b)<<16) + b/2)/b;
9e2a16e1
MN
79 }
80 return out;
81}
82
2d2fe557 83#endif
67cbe681
MN
84static uint64_t int_sqrt(uint64_t a)
85{
86 uint64_t ret=0;
87 int s;
88 uint64_t ret_sq=0;
89
90 for(s=31; s>=0; s--){
91 uint64_t b= ret_sq + (1ULL<<(s*2)) + (ret<<s)*2;
92 if(b<=a){
93 ret_sq=b;
94 ret+= 1ULL<<s;
95 }
96 }
97 return ret;
98}
99
100int main(int argc,char* argv[]){
101 int i, j;
102 uint64_t sse=0;
103 uint64_t dev;
104 FILE *f[2];
105 uint8_t buf[2][SIZE];
9e2a16e1 106 uint64_t psnr;
ba96e97f 107 int len= argc<4 ? 1 : atoi(argv[3]);
0c90161f 108 int64_t max= (1<<(8*len))-1;
ba96e97f 109 int shift= argc<5 ? 0 : atoi(argv[4]);
b8889ea5 110 int skip_bytes = argc<6 ? 0 : atoi(argv[5]);
115329f1 111
0c90161f 112 if(argc<3){
b8889ea5
BL
113 printf("tiny_psnr <file1> <file2> [<elem size> [<shift> [<skip bytes>]]]\n");
114 printf("for wav files use the following:\n");
115 printf("./tiny_psnr file1.wav file2.wav 2 0 44 to skip the header.\n");
67cbe681
MN
116 return -1;
117 }
115329f1 118
0d6d0cf9
MN
119 f[0]= fopen(argv[1], "rb");
120 f[1]= fopen(argv[2], "rb");
ba96e97f 121 fseek(f[shift<0], shift < 0 ? -shift : shift, SEEK_SET);
67cbe681 122
b8889ea5
BL
123 fseek(f[0],skip_bytes,SEEK_CUR);
124 fseek(f[1],skip_bytes,SEEK_CUR);
125
67cbe681
MN
126 for(i=0;;){
127 if( fread(buf[0], SIZE, 1, f[0]) != 1) break;
128 if( fread(buf[1], SIZE, 1, f[1]) != 1) break;
115329f1 129
67cbe681 130 for(j=0; j<SIZE; i++,j++){
0c90161f
MN
131 int64_t a= buf[0][j];
132 int64_t b= buf[1][j];
133 if(len==2){
134 a= (int16_t)(a | (buf[0][++j]<<8));
135 b= (int16_t)(b | (buf[1][ j]<<8));
136 }
67cbe681
MN
137 sse += (a-b) * (a-b);
138 }
139 }
115329f1 140
eeaa742c 141 if(!i) i=1;
0c90161f 142 dev= int_sqrt( ((sse/i)*F*F) + (((sse%i)*F*F) + i/2)/i );
9e2a16e1 143 if(sse)
0c90161f 144 psnr= ((2*log16(max<<16) + log16(i) - log16(sse))*284619LL*F + (1<<31)) / (1LL<<32);
9e2a16e1
MN
145 else
146 psnr= 100*F-1; //floating point free infinity :)
115329f1
DB
147
148 printf("stddev:%3d.%02d PSNR:%2d.%02d bytes:%d\n",
149 (int)(dev/F), (int)(dev%F),
9e2a16e1 150 (int)(psnr/F), (int)(psnr%F),
ddbddce5 151 i*len);
67cbe681
MN
152 return 0;
153}
9e2a16e1
MN
154
155