Advertisement
Guest User

Untitled

a guest
Mar 23rd, 2013
62
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.48 KB | None | 0 0
  1. /*
  2. * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
  3. *
  4. * This file is part of FFmpeg.
  5. *
  6. * FFmpeg is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2.1 of the License, or (at your option) any later version.
  10. *
  11. * FFmpeg is distributed in the hope that it will be useful,
  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
  17. * License along with FFmpeg; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  19. */
  20.  
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <string.h>
  24. #include <inttypes.h>
  25. #include <assert.h>
  26.  
  27. void vp8_ssim_parms_8x8_c(unsigned char *s,
  28. int sp,
  29. unsigned char *r,
  30. int rp,
  31. unsigned long *sum_s,
  32. unsigned long *sum_r,
  33. unsigned long *sum_sq_s,
  34. unsigned long *sum_sq_r,
  35. unsigned long *sum_sxr)
  36. {
  37. int i,j;
  38. for(i=0;i<8;i++,s+=sp,r+=rp)
  39. {
  40. for(j=0;j<8;j++)
  41. {
  42. *sum_s += s[j];
  43. *sum_r += r[j];
  44. *sum_sq_s += s[j] * s[j];
  45. *sum_sq_r += r[j] * r[j];
  46. *sum_sxr += s[j] * r[j];
  47. }
  48. }
  49. }
  50.  
  51. const static int64_t cc1 = 26634; // (64^2*(.01*255)^2
  52. const static int64_t cc2 = 239708; // (64^2*(.03*255)^2
  53.  
  54. static double similarity(unsigned long sum_s,
  55. unsigned long sum_r,
  56. unsigned long sum_sq_s,
  57. unsigned long sum_sq_r,
  58. unsigned long sum_sxr,
  59. int count)
  60. {
  61. int64_t ssim_n, ssim_d;
  62. int64_t c1, c2;
  63.  
  64. //scale the constants by number of pixels
  65. c1 = (cc1*count*count)>>12;
  66. c2 = (cc2*count*count)>>12;
  67.  
  68. ssim_n = (2*sum_s*sum_r+ c1)*((int64_t) 2*count*sum_sxr-
  69. (int64_t) 2*sum_s*sum_r+c2);
  70.  
  71. ssim_d = (sum_s*sum_s +sum_r*sum_r+c1)*
  72. ((int64_t)count*sum_sq_s-(int64_t)sum_s*sum_s +
  73. (int64_t)count*sum_sq_r-(int64_t) sum_r*sum_r +c2) ;
  74.  
  75. return ssim_n * 1.0 / ssim_d;
  76. }
  77.  
  78. static double ssim_8x8(unsigned char *s,int sp, unsigned char *r,int rp)
  79. {
  80. unsigned long sum_s=0,sum_r=0,sum_sq_s=0,sum_sq_r=0,sum_sxr=0;
  81. vp8_ssim_parms_8x8_c(s, sp, r, rp, &sum_s, &sum_r, &sum_sq_s, &sum_sq_r, &sum_sxr);
  82. return similarity(sum_s, sum_r, sum_sq_s, sum_sq_r, sum_sxr, 64);
  83. }
  84.  
  85. // We are using a 8x8 moving window with starting location of each 8x8 window
  86. // on the 4x4 pixel grid. Such arrangement allows the windows to overlap
  87. // block boundaries to penalize blocking artifacts.
  88. double vp8_ssim2(unsigned char *img1,
  89. unsigned char *img2,
  90. int stride_img1,
  91. int stride_img2,
  92. int width,
  93. int height)
  94. {
  95. int i,j;
  96. int samples =0;
  97. double ssim_total=0;
  98.  
  99. // sample point start with each 4x4 location
  100. for(i=0; i < height-8; i+=4, img1 += stride_img1*4, img2 += stride_img2*4)
  101. {
  102. for(j=0; j < width-8; j+=4 )
  103. {
  104. double v = ssim_8x8(img1+j, stride_img1, img2+j, stride_img2);
  105. ssim_total += v;
  106. samples++;
  107. }
  108. }
  109. ssim_total /= samples;
  110. return ssim_total;
  111. }
  112.  
  113. int main(int argc, char *argv[])
  114. {
  115. FILE *f[2];
  116. uint8_t *buf[2];
  117. int size[2];
  118. int w, h;
  119. double ssim;
  120.  
  121. f[0] = fopen(argv[1], "rb");
  122. f[1] = fopen(argv[2], "rb");
  123. sscanf(argv[3], "%dx%d", &w, &h);
  124. if (!f[0] || !f[1]) {
  125. fprintf(stderr, "Could not open input files.\n");
  126. return 1;
  127. }
  128. fseek(f[0], 0, SEEK_END);
  129. fseek(f[1], 0, SEEK_END);
  130. size[0] = ftell(f[0]);
  131. size[1] = ftell(f[1]);
  132. assert(size[0] == w * h);
  133. assert(size[1] == w * h);
  134. buf[0] = malloc(size[0]);
  135. buf[1] = malloc(size[1]);
  136. fseek(f[0], 0, SEEK_SET);
  137. fseek(f[1], 0, SEEK_SET);
  138. fread(buf[0], size[0], 1, f[0]);
  139. fread(buf[1], size[1], 1, f[1]);
  140. ssim = vp8_ssim2(buf[0], buf[1], w, w, w, h);
  141. printf("SSIM: %lf\n", ssim);
  142.  
  143. return 0;
  144. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement