ffmpeg / tests / tiny_psnr.c @ 47805d21
History  View  Annotate  Download (3.35 KB)
1 
/*


2 
* Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>

3 
*

4 
* This library is free software; you can redistribute it and/or

5 
* modify it under the terms of the GNU Lesser General Public

6 
* License as published by the Free Software Foundation; either

7 
* version 2 of the License, or (at your option) any later version.

8 
*

9 
* This library is distributed in the hope that it will be useful,

10 
* but WITHOUT ANY WARRANTY; without even the implied warranty of

11 
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU

12 
* Lesser General Public License for more details.

13 
*

14 
* You should have received a copy of the GNU Lesser General Public

15 
* License along with this library; if not, write to the Free Software

16 
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 021111307 USA

17 
*

18 
*/

19  
20 
#include <stdio.h> 
21 
#include <stdlib.h> 
22 
#include <inttypes.h> 
23 
#include <assert.h> 
24  
25 
#define F 100 
26 
#define SIZE 2048 
27  
28 
uint64_t exp16_table[21]={

29 
65537,

30 
65538,

31 
65540,

32 
65544,

33 
65552,

34 
65568,

35 
65600,

36 
65664,

37 
65793,

38 
66050,

39 
66568,

40 
67616,

41 
69763,

42 
74262,

43 
84150,

44 
108051,

45 
178145,

46 
484249,

47 
3578144,

48 
195360063,

49 
582360139072LL,

50 
}; 
51 
#if 1 
52 
// 16.16 fixpoint exp()

53 
static unsigned int exp16(unsigned int a){ 
54 
int i;

55 
int out= 1<<16; 
56  
57 
for(i=19;i>=0;i){ 
58 
if(a&(1<<i)) 
59 
out= (out*exp16_table[i] + (1<<15))>>16; 
60 
} 
61  
62 
return out;

63 
} 
64 
// 16.16 fixpoint log()

65 
static int64_t log16(uint64_t a){

66 
int i;

67 
int out=0; 
68  
69 
if(a < 1<<16) 
70 
return log16((1LL<<32) / a); 
71 
a<<=16;

72 

73 
for(i=20;i>=0;i){ 
74 
int64_t b= exp16_table[i]; 
75 
if(a<(b<<16)) continue; 
76 
out = 1<<i;

77 
a = ((a/b)<<16) + (((a%b)<<16) + b/2)/b; 
78 
} 
79 
return out;

80 
} 
81  
82 
#endif

83 
static uint64_t int_sqrt(uint64_t a)

84 
{ 
85 
uint64_t ret=0;

86 
int s;

87 
uint64_t ret_sq=0;

88  
89 
for(s=31; s>=0; s){ 
90 
uint64_t b= ret_sq + (1ULL<<(s*2)) + (ret<<s)*2; 
91 
if(b<=a){

92 
ret_sq=b; 
93 
ret+= 1ULL<<s;

94 
} 
95 
} 
96 
return ret;

97 
} 
98  
99 
int main(int argc,char* argv[]){ 
100 
int i, j;

101 
uint64_t sse=0;

102 
uint64_t dev; 
103 
FILE *f[2];

104 
uint8_t buf[2][SIZE];

105 
uint64_t psnr; 
106 
int len= argc<4 ? 1 : atoi(argv[3]); 
107 
int64_t max= (1<<(8*len))1; 
108 
int shift= argc<5 ? 0 : atoi(argv[4]); 
109 

110 
if(argc<3){ 
111 
printf("tiny_psnr <file1> <file2> [<elem size> [<shift>]]\n");

112 
return 1; 
113 
} 
114 

115 
f[0]= fopen(argv[1], "rb"); 
116 
f[1]= fopen(argv[2], "rb"); 
117 
fseek(f[shift<0], shift < 0 ? shift : shift, SEEK_SET); 
118  
119 
for(i=0;;){ 
120 
if( fread(buf[0], SIZE, 1, f[0]) != 1) break; 
121 
if( fread(buf[1], SIZE, 1, f[1]) != 1) break; 
122 

123 
for(j=0; j<SIZE; i++,j++){ 
124 
int64_t a= buf[0][j];

125 
int64_t b= buf[1][j];

126 
if(len==2){ 
127 
a= (int16_t)(a  (buf[0][++j]<<8)); 
128 
b= (int16_t)(b  (buf[1][ j]<<8)); 
129 
} 
130 
sse += (ab) * (ab); 
131 
} 
132 
} 
133 

134 
if(!i) i=1; 
135 
dev= int_sqrt( ((sse/i)*F*F) + (((sse%i)*F*F) + i/2)/i );

136 
if(sse)

137 
psnr= ((2*log16(max<<16) + log16(i)  log16(sse))*284619LL*F + (1<<31)) / (1LL<<32); 
138 
else

139 
psnr= 100*F1; //floating point free infinity :) 
140 

141 
printf("stddev:%3d.%02d PSNR:%2d.%02d bytes:%d\n",

142 
(int)(dev/F), (int)(dev%F), 
143 
(int)(psnr/F), (int)(psnr%F), 
144 
i); 
145 
return 0; 
146 
} 
147  
148 