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