resample: replace VLA with malloc/free
[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 25
1e90317b 26#define FFMIN(a,b) ((a) > (b) ? (b) : (a))
67cbe681
MN
27#define F 100
28#define SIZE 2048
29
0c90161f 30uint64_t exp16_table[21]={
9e2a16e1
MN
31 65537,
32 65538,
33 65540,
34 65544,
35 65552,
36 65568,
37 65600,
38 65664,
39 65793,
40 66050,
41 66568,
42 67616,
43 69763,
44 74262,
45 84150,
46 108051,
47 178145,
48 484249,
49 3578144,
50 195360063,
0c90161f 51 582360139072LL,
9e2a16e1 52};
e9b67fe4
DB
53
54#if 0
2d2fe557
DB
55// 16.16 fixpoint exp()
56static unsigned int exp16(unsigned int a){
57 int i;
58 int out= 1<<16;
59
60 for(i=19;i>=0;i--){
61 if(a&(1<<i))
62 out= (out*exp16_table[i] + (1<<15))>>16;
63 }
9e2a16e1 64
2d2fe557
DB
65 return out;
66}
e9b67fe4
DB
67#endif
68
9e2a16e1 69// 16.16 fixpoint log()
0c90161f 70static int64_t log16(uint64_t a){
9e2a16e1
MN
71 int i;
72 int out=0;
0c90161f
MN
73
74 if(a < 1<<16)
75 return -log16((1LL<<32) / a);
9e2a16e1 76 a<<=16;
115329f1 77
0c90161f 78 for(i=20;i>=0;i--){
8176bd1a
MN
79 int64_t b= exp16_table[i];
80 if(a<(b<<16)) continue;
9e2a16e1 81 out |= 1<<i;
8176bd1a 82 a = ((a/b)<<16) + (((a%b)<<16) + b/2)/b;
9e2a16e1
MN
83 }
84 return out;
85}
86
67cbe681
MN
87static uint64_t int_sqrt(uint64_t a)
88{
89 uint64_t ret=0;
90 int s;
91 uint64_t ret_sq=0;
92
93 for(s=31; s>=0; s--){
94 uint64_t b= ret_sq + (1ULL<<(s*2)) + (ret<<s)*2;
95 if(b<=a){
96 ret_sq=b;
97 ret+= 1ULL<<s;
98 }
99 }
100 return ret;
101}
102
103int main(int argc,char* argv[]){
104 int i, j;
105 uint64_t sse=0;
106 uint64_t dev;
107 FILE *f[2];
108 uint8_t buf[2][SIZE];
9e2a16e1 109 uint64_t psnr;
ba96e97f 110 int len= argc<4 ? 1 : atoi(argv[3]);
0c90161f 111 int64_t max= (1<<(8*len))-1;
ba96e97f 112 int shift= argc<5 ? 0 : atoi(argv[4]);
b8889ea5 113 int skip_bytes = argc<6 ? 0 : atoi(argv[5]);
1e90317b
MN
114 int size0=0;
115 int size1=0;
cb0067ec 116 int maxdist = 0;
115329f1 117
0c90161f 118 if(argc<3){
b8889ea5 119 printf("tiny_psnr <file1> <file2> [<elem size> [<shift> [<skip bytes>]]]\n");
cc8de8e8 120 printf("For WAV files use the following:\n");
b8889ea5 121 printf("./tiny_psnr file1.wav file2.wav 2 0 44 to skip the header.\n");
67cbe681
MN
122 return -1;
123 }
115329f1 124
0d6d0cf9
MN
125 f[0]= fopen(argv[1], "rb");
126 f[1]= fopen(argv[2], "rb");
e740c796 127 if(!f[0] || !f[1]){
cc8de8e8 128 fprintf(stderr, "Could not open input files.\n");
e740c796
MN
129 return -1;
130 }
ba96e97f 131 fseek(f[shift<0], shift < 0 ? -shift : shift, SEEK_SET);
67cbe681 132
b8889ea5
BL
133 fseek(f[0],skip_bytes,SEEK_CUR);
134 fseek(f[1],skip_bytes,SEEK_CUR);
135
1e90317b
MN
136 for(;;){
137 int s0= fread(buf[0], 1, SIZE, f[0]);
138 int s1= fread(buf[1], 1, SIZE, f[1]);
115329f1 139
1e90317b 140 for(j=0; j<FFMIN(s0,s1); j++){
0c90161f
MN
141 int64_t a= buf[0][j];
142 int64_t b= buf[1][j];
cb0067ec 143 int dist;
0c90161f
MN
144 if(len==2){
145 a= (int16_t)(a | (buf[0][++j]<<8));
146 b= (int16_t)(b | (buf[1][ j]<<8));
147 }
67cbe681 148 sse += (a-b) * (a-b);
cb0067ec
VS
149 dist = abs(a-b);
150 if (dist > maxdist) maxdist = dist;
67cbe681 151 }
1e90317b
MN
152 size0 += s0;
153 size1 += s1;
154 if(s0+s1<=0)
155 break;
67cbe681 156 }
115329f1 157
1e90317b 158 i= FFMIN(size0,size1)/len;
eeaa742c 159 if(!i) i=1;
0c90161f 160 dev= int_sqrt( ((sse/i)*F*F) + (((sse%i)*F*F) + i/2)/i );
9e2a16e1 161 if(sse)
b00803e0 162 psnr= ((2*log16(max<<16) + log16(i) - log16(sse))*284619LL*F + (1LL<<31)) / (1LL<<32);
9e2a16e1 163 else
1e90317b 164 psnr= 1000*F-1; //floating point free infinity :)
115329f1 165
cb0067ec 166 printf("stddev:%5d.%02d PSNR:%3d.%02d MAXDIFF:%5d bytes:%9d/%9d\n",
115329f1 167 (int)(dev/F), (int)(dev%F),
9e2a16e1 168 (int)(psnr/F), (int)(psnr%F),
cb0067ec 169 maxdist,
1e90317b 170 size0, size1);
67cbe681
MN
171 return 0;
172}
9e2a16e1
MN
173
174