[cvs] / xvidcore / src / plugins / plugin_ssim.c Repository:
ViewVC logotype

Diff of /xvidcore/src/plugins/plugin_ssim.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.6, Wed Nov 8 06:55:27 2006 UTC revision 1.12, Thu Nov 27 20:34:53 2008 UTC
# Line 23  Line 23 
23   *   *
24   ****************************************************************************/   ****************************************************************************/
25    
26  #include <malloc.h>  #include <stdlib.h>
27  #include <stdio.h>  #include <stdio.h>
28  #include <math.h>  #include <math.h>
29  #include "../portab.h"  #include "../portab.h"
# Line 39  Line 39 
39    
40  /*dev 1.0 gaussian weighting. the weight for the pixel x,y is w(x)*w(y)*/  /*dev 1.0 gaussian weighting. the weight for the pixel x,y is w(x)*w(y)*/
41  static float mask8[8] = {  static float mask8[8] = {
42          0.0069815, 0.1402264, 1.0361408, 2.8165226,          0.0069815f, 0.1402264f, 1.0361408f, 2.8165226f,
43          2.8165226, 1.0361408, 0.1402264, 0.0069815          2.8165226f, 1.0361408f, 0.1402264f, 0.0069815f
44  };  };
45    
46    /* integer version. Norm: coeffs sums up to 4096.
47      Define USE_INT_GAUSSIAN to use it as replacement to float version */
48    
49    /* #define USE_INT_GAUSSIAN */
50    static const uint16_t imask8[8] = {
51      4, 72, 530, 1442, 1442, 530, 72, 4
52    };
53    #define GACCUM(X)  ( ((X)+(1<<11)) >> 12 )
54    
55    
56  struct framestat_t{  struct framestat_t{
57          int type;          int type;
58          int quant;          int quant;
# Line 238  Line 248 
248                  sum *=mask8[i];                  sum *=mask8[i];
249                  mean += sum;                  mean += sum;
250          }          }
251          return (int) mean + 0.5;          return (int) (mean + 0.5);
252    }
253    
254    int lum_8x8_gaussian_int(uint8_t* ptr, int stride){
255            uint32_t mean;
256            int i,j;
257            mean = 0;
258            for(i=0;i<8;i++){
259                    uint32_t sum = 0;
260                    for(j=0;j<8;j++)
261                            sum += ptr[i*stride + j]*imask8[j];
262    
263                    sum = GACCUM(sum) * imask8[i];
264                    mean += sum;
265            }
266            return (int)GACCUM(mean);
267  }  }
268    
269  /*calculate the difference between two blocks next to each other on a row*/  /*calculate the difference between two blocks next to each other on a row*/
# Line 279  Line 304 
304          ptrc += str;          ptrc += str;
305          }          }
306    
307          *pdevo = (int) (devo - ((lumo*lumo + 32) >> 6)) + 0.5;          *pdevo = (int) ((devo - ((lumo*lumo + 32) >> 6)) + 0.5);
308          *pdevc = (int) (devc - ((lumc*lumc + 32) >> 6)) + 0.5;          *pdevc = (int) ((devc - ((lumc*lumc + 32) >> 6)) + 0.5);
309          *pcorr = (int) (corr - ((lumo*lumc + 32) >> 6)) + 0.5;          *pcorr = (int) ((corr - ((lumo*lumc + 32) >> 6)) + 0.5);
310    };
311    
312    void consim_gaussian_int(uint8_t* ptro, uint8_t* ptrc, int stride, int lumo, int lumc, int* pdevo, int* pdevc, int* pcorr)
313    {
314            unsigned int valo, valc,i,j,str;
315            uint32_t  devo=0, devc=0, corr=0;
316            str = stride - 8;
317            for(i=0;i< 8;i++){
318                    uint32_t sumo = 0;
319                    uint32_t sumc = 0;
320                    uint32_t sumcorr = 0;
321                    for(j=0;j< 8;j++){
322                            valo = *ptro;
323                            valc = *ptrc;
324                            sumo += valo*valo*imask8[j];
325                            sumc += valc*valc*imask8[j];
326                            sumcorr += valo*valc*imask8[j];
327                            ptro++;
328                            ptrc++;
329                    }
330    
331            devo += GACCUM(sumo)*imask8[i];
332            devc += GACCUM(sumc)*imask8[i];
333            corr += GACCUM(sumcorr)*imask8[i];
334            ptro += str;
335            ptrc += str;
336            }
337    
338            devo = GACCUM(devo);
339            devc = GACCUM(devc);
340            corr = GACCUM(corr);
341            *pdevo = (int) ((devo - ((lumo*lumo + 32) >> 6)) + 0.5);
342            *pdevc = (int) ((devc - ((lumc*lumc + 32) >> 6)) + 0.5);
343            *pcorr = (int) ((corr - ((lumo*lumc + 32) >> 6)) + 0.5);
344  };  };
345    
346  /*calculate contrast and correlation of the two blocks*/  /*calculate contrast and correlation of the two blocks*/
# Line 309  Line 368 
368    
369  /*calculate the final ssim value*/  /*calculate the final ssim value*/
370  static float calc_ssim(float meano, float meanc, float devo, float devc, float corr){  static float calc_ssim(float meano, float meanc, float devo, float devc, float corr){
371          static const float c1 = (0.01*255)*(0.01*255);          static const float c1 = (0.01f*255)*(0.01f*255);
372          static const float c2 = (0.03*255)*(0.03*255);          static const float c2 = (0.03f*255)*(0.03f*255);
373          /*printf("meano: %f meanc: %f devo: %f devc: %f corr: %f\n",meano,meanc,devo,devc,corr);*/          /*printf("meano: %f meanc: %f devo: %f devc: %f corr: %f\n",meano,meanc,devo,devc,corr);*/
374          return ((2.0*meano*meanc + c1)*(corr/32.0 + c2))/((meano*meano + meanc*meanc + c1)*(devc/64.0 + devo/64.0 + c2));          return ((2.0f*meano*meanc + c1)*(corr/32.0f + c2))/((meano*meano + meanc*meanc + c1)*(devc/64.0f + devo/64.0f + c2));
375  }  }
376    
377  static void ssim_after(xvid_plg_data_t* data, ssim_data_t* ssim){  static void ssim_after(xvid_plg_data_t* data, ssim_data_t* ssim){
# Line 407  Line 466 
466  static int ssim_create(xvid_plg_create_t* create, void** handle){  static int ssim_create(xvid_plg_create_t* create, void** handle){
467          ssim_data_t* ssim;          ssim_data_t* ssim;
468          plg_ssim_param_t* param;          plg_ssim_param_t* param;
         int cpu_flags;  
469          param = (plg_ssim_param_t*) malloc(sizeof(plg_ssim_param_t));          param = (plg_ssim_param_t*) malloc(sizeof(plg_ssim_param_t));
470          *param = *((plg_ssim_param_t*) create->param);          *param = *((plg_ssim_param_t*) create->param);
471          ssim = (ssim_data_t*) malloc(sizeof(ssim_data_t));          ssim = (ssim_data_t*) malloc(sizeof(ssim_data_t));
472    
         cpu_flags = check_cpu_features();  
   
473          ssim->func8x8 = lum_8x8_c;          ssim->func8x8 = lum_8x8_c;
474          ssim->func2x8 = lum_2x8_c;          ssim->func2x8 = lum_2x8_c;
475          ssim->consim = consim_c;          ssim->consim = consim_c;
# Line 422  Line 478 
478    
479          ssim->grid = param->acc;          ssim->grid = param->acc;
480    
481  #if defined(ARCH_IS_IA32)  #if defined(ARCH_IS_IA32) || defined(ARCH_IS_X86_64)
482            {
483            int cpu_flags = (param->cpu_flags & XVID_CPU_FORCE) ? param->cpu_flags : check_cpu_features();
484    
485          if((cpu_flags & XVID_CPU_MMX) && (param->acc > 0)){          if((cpu_flags & XVID_CPU_MMX) && (param->acc > 0)){
486                  ssim->func8x8 = lum_8x8_mmx;                  ssim->func8x8 = lum_8x8_mmx;
487                  ssim->consim = consim_mmx;                  ssim->consim = consim_mmx;
# Line 430  Line 489 
489          if((cpu_flags & XVID_CPU_SSE2) && (param->acc > 0)){          if((cpu_flags & XVID_CPU_SSE2) && (param->acc > 0)){
490                  ssim->consim = consim_sse2;                  ssim->consim = consim_sse2;
491          }          }
492            }
493  #endif  #endif
494    
495          /*gaussian weigthing not implemented*/          /*gaussian weigthing not implemented*/
496    #if !defined(USE_INT_GAUSSIAN)
497          if(ssim->grid == 0){          if(ssim->grid == 0){
498                  ssim->grid = 1;                  ssim->grid = 1;
499                  ssim->func8x8 = lum_8x8_gaussian;                  ssim->func8x8 = lum_8x8_gaussian;
500                  ssim->func2x8 = NULL;                  ssim->func2x8 = NULL;
501                  ssim->consim = consim_gaussian;                  ssim->consim = consim_gaussian;
502          }          }
503    #else
504            if(ssim->grid == 0){
505                    ssim->grid = 1;
506                    ssim->func8x8 = lum_8x8_gaussian_int;
507                    ssim->func2x8 = NULL;
508                    ssim->consim = consim_gaussian_int;
509            }
510    #endif
511          if(ssim->grid > 4) ssim->grid = 4;          if(ssim->grid > 4) ssim->grid = 4;
512    
513          ssim->ssim_sum = 0.0;          ssim->ssim_sum = 0.0;

Legend:
Removed from v.1.6  
changed lines
  Added in v.1.12

No admin address has been configured
ViewVC Help
Powered by ViewVC 1.0.4