timgfiltersmoother.cpp

来自「从FFMPEG转换而来的H264解码程序,VC下编译..」· C++ 代码 · 共 464 行 · 第 1/2 页

CPP
464
字号
/*
 * Copyright (c) 2002-2006 Milan Cutka
 * based on VirtualDub Smoother filter by Avery Lee
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License,or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not,write to the Free Software
 * Foundation,Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "stdafx.h"
#include "TimgFilterSmoother.h"
#include "TblurSettings.h"

//================================= TimgFilterSmootherLuma::Tblur =================================
void TimgFilterSmootherLuma::Tblur::avgrow(const unsigned char *src,unsigned char *dst,unsigned int width)
{
 int r0=*src++;

 int sum=r0*4;

 unsigned int w=1;
 do
 {
  unsigned char c=src[0];
  sum+=c;
  ++src;
 } while(--w);

 w=3;
 do
 {
  unsigned char c=src[0];
  sum=sum+c-r0;
  *dst++=(unsigned char)(sum/5);
  ++src;
 } while(--w);

 w=width-6;
 do
 {
  unsigned char c=src[0],d=src[-5];
  sum=sum+c-d;
  *dst++=(unsigned char)(sum/5);
  ++src;
 } while(--w);

 r0=*src++;

 w=3;
 do
 {
  unsigned char d=src[-5];
  sum=sum-d+r0;
  *dst++=(unsigned char)(sum/5);
  ++src;
 } while(--w);
}
void TimgFilterSmootherLuma::Tblur::filtrow_1(unsigned char *sum,const unsigned char *src,unsigned int dx,stride_t stride,int thresh)
{
 long bitarray=0;
 src=src-stride;

 do
 {
  // Fetch surrounding pixels.
  unsigned char pl=*((src-1)+stride);
  unsigned char pr=*((src+1)+stride);
  unsigned char pu=*src;
  unsigned char pd=*(src+stride*2);

  // Compute gradient at pixel.
  int grad_x=pr-pl;
  int grad_y=pu-pd;

  bitarray >>=1;

  //		if (grad_x*grad_x+grad_y*grad_y > thresh) {
  if (smoother_blur_square_table[765+grad_x]+smoother_blur_square_table[765+grad_y] > thresh)
   bitarray |=16;

  *sum++=smoother_blur_codes[bitarray];
  ++src;
 } while(--dx>0);
 *sum++=smoother_blur_codes[bitarray>>1];
 *sum++=smoother_blur_codes[bitarray>>2];
}
TimgFilterSmootherLuma::Tblur::Tblur(unsigned int Idx,unsigned int Idy):dx(Idx),dy(Idy)
{
 for (int i=0;i<5;i++) sum_row[i]=new unsigned char[dx+2];
 for (int i=0;i<5;i++) avg_row[i]=new unsigned char[dx];
}
TimgFilterSmootherLuma::Tblur::~Tblur()
{
 for(int i=0;i<5;i++) if (sum_row[i]) delete []sum_row[i];
 for(int i=0;i<5;i++) if (avg_row[i]) delete []avg_row[i];
}
void TimgFilterSmootherLuma::Tblur::run(const unsigned char *src,stride_t srcStride,unsigned char *dst,stride_t dstStride,int g_thresh)
{
 long w,h,x;
 int next_row=0,next_avg_row=0;
 unsigned char *avg_rows[5];
 unsigned char *row[5];
 int i;

 const unsigned char *srcf;
 unsigned char *avg;

 srcf=src;

 avgrow(src+0*srcStride,avg_row[1],dx);
 memcpy(avg_row[2],avg_row[1],dx);
 memcpy(avg_row[3],avg_row[1],dx);
 avgrow(src+1*srcStride,avg_row[4],dx);

 memset(sum_row[1],0,dx+2);
 memset(sum_row[2],0,dx+2);
 memset(sum_row[3],0,dx+2);

 filtrow_1(sum_row[4],(srcf+1)+srcStride,dx-2,srcStride,g_thresh);

 h=dy;
 do
 {
  if (h>3)
   filtrow_1(sum_row[next_row],(srcf+1)+srcStride*2,dx-2,srcStride,g_thresh);
  else
   memset(sum_row[next_row],0,dx+2);

  avg=avg_row[next_avg_row];

  if (h>2)
   avgrow(src+2*srcStride,avg,dx);
  else
   memcpy(avg,avg_row[(next_avg_row+4)%5],dx);

  if (++next_row>=5) next_row=0;
  for(i=0;i<5;i++) row[i]=sum_row[(next_row+i)%5];
  if (++next_avg_row>=5) next_avg_row=0;
  for(i=0;i<5;i++) avg_rows[i]=avg_row[(next_avg_row+i)%5];

  w=dx;
  x=0;
  do
  {
   int s=(int)(row[0][x]&0xe0)+(int)row[1][x]+(int)row[2][x]+(int)row[3][x]+(int)(row[4][x]&0xe0);
   int A=s&31;

   if (A>3)
    *dst=*src;
   else
    {
     int B=s>>5;

     int p0=avg_rows[0][x];
     int p1=avg_rows[1][x];
     int p2=avg_rows[2][x];
     int p3=avg_rows[3][x];
     int p4=avg_rows[4][x];
     int r=p0+p1*2+p2*2+p3*2+p4;

     if (A>1)
      {
       int d=*src;
       r+=d<<3;
       *dst=(unsigned char)(r>>4);
      }
     else if (B>3)
      {
       int d=*src;
       r=r*3+(d<<3);
       *dst=(unsigned char)(r>>5);
      }
     else
      *dst=(unsigned char)(r>>3);
    }
   ++src;
   ++dst;
  } while(++x<w);
  src+=srcStride-dx;
  dst+=dstStride-dx;
  srcf+=srcStride;
 } while(--h>0);
}

const int TimgFilterSmootherLuma::Tblur::smoother_blur_square_table[765*2+1]=
{
 0x0008ee09,0x0008e810,0x0008e219,0x0008dc24,0x0008d631,0x0008d040,0x0008ca51,0x0008c464,
 0x0008be79,0x0008b890,0x0008b2a9,0x0008acc4,0x0008a6e1,0x0008a100,0x00089b21,0x00089544,
 0x00088f69,0x00088990,0x000883b9,0x00087de4,0x00087811,0x00087240,0x00086c71,0x000866a4,
 0x000860d9,0x00085b10,0x00085549,0x00084f84,0x000849c1,0x00084400,0x00083e41,0x00083884,
 0x000832c9,0x00082d10,0x00082759,0x000821a4,0x00081bf1,0x00081640,0x00081091,0x00080ae4,
 0x00080539,0x0007ff90,0x0007f9e9,0x0007f444,0x0007eea1,0x0007e900,0x0007e361,0x0007ddc4,
 0x0007d829,0x0007d290,0x0007ccf9,0x0007c764,0x0007c1d1,0x0007bc40,0x0007b6b1,0x0007b124,
 0x0007ab99,0x0007a610,0x0007a089,0x00079b04,0x00079581,0x00079000,0x00078a81,0x00078504,
 0x00077f89,0x00077a10,0x00077499,0x00076f24,0x000769b1,0x00076440,0x00075ed1,0x00075964,
 0x000753f9,0x00074e90,0x00074929,0x000743c4,0x00073e61,0x00073900,0x000733a1,0x00072e44,
 0x000728e9,0x00072390,0x00071e39,0x000718e4,0x00071391,0x00070e40,0x000708f1,0x000703a4,
 0x0006fe59,0x0006f910,0x0006f3c9,0x0006ee84,0x0006e941,0x0006e400,0x0006dec1,0x0006d984,
 0x0006d449,0x0006cf10,0x0006c9d9,0x0006c4a4,0x0006bf71,0x0006ba40,0x0006b511,0x0006afe4,
 0x0006aab9,0x0006a590,0x0006a069,0x00069b44,0x00069621,0x00069100,0x00068be1,0x000686c4,
 0x000681a9,0x00067c90,0x00067779,0x00067264,0x00066d51,0x00066840,0x00066331,0x00065e24,
 0x00065919,0x00065410,0x00064f09,0x00064a04,0x00064501,0x00064000,0x00063b01,0x00063604,
 0x00063109,0x00062c10,0x00062719,0x00062224,0x00061d31,0x00061840,0x00061351,0x00060e64,
 0x00060979,0x00060490,0x0005ffa9,0x0005fac4,0x0005f5e1,0x0005f100,0x0005ec21,0x0005e744,
 0x0005e269,0x0005dd90,0x0005d8b9,0x0005d3e4,0x0005cf11,0x0005ca40,0x0005c571,0x0005c0a4,
 0x0005bbd9,0x0005b710,0x0005b249,0x0005ad84,0x0005a8c1,0x0005a400,0x00059f41,0x00059a84,
 0x000595c9,0x00059110,0x00058c59,0x000587a4,0x000582f1,0x00057e40,0x00057991,0x000574e4,
 0x00057039,0x00056b90,0x000566e9,0x00056244,0x00055da1,0x00055900,0x00055461,0x00054fc4,
 0x00054b29,0x00054690,0x000541f9,0x00053d64,0x000538d1,0x00053440,0x00052fb1,0x00052b24,
 0x00052699,0x00052210,0x00051d89,0x00051904,0x00051481,0x00051000,0x00050b81,0x00050704,
 0x00050289,0x0004fe10,0x0004f999,0x0004f524,0x0004f0b1,0x0004ec40,0x0004e7d1,0x0004e364,
 0x0004def9,0x0004da90,0x0004d629,0x0004d1c4,0x0004cd61,0x0004c900,0x0004c4a1,0x0004c044,
 0x0004bbe9,0x0004b790,0x0004b339,0x0004aee4,0x0004aa91,0x0004a640,0x0004a1f1,0x00049da4,
 0x00049959,0x00049510,0x000490c9,0x00048c84,0x00048841,0x00048400,0x00047fc1,0x00047b84,
 0x00047749,0x00047310,0x00046ed9,0x00046aa4,0x00046671,0x00046240,0x00045e11,0x000459e4,
 0x000455b9,0x00045190,0x00044d69,0x00044944,0x00044521,0x00044100,0x00043ce1,0x000438c4,
 0x000434a9,0x00043090,0x00042c79,0x00042864,0x00042451,0x00042040,0x00041c31,0x00041824,
 0x00041419,0x00041010,0x00040c09,0x00040804,0x00040401,0x00040000,0x0003fc01,0x0003f804,
 0x0003f409,0x0003f010,0x0003ec19,0x0003e824,0x0003e431,0x0003e040,0x0003dc51,0x0003d864,
 0x0003d479,0x0003d090,0x0003cca9,0x0003c8c4,0x0003c4e1,0x0003c100,0x0003bd21,0x0003b944,
 0x0003b569,0x0003b190,0x0003adb9,0x0003a9e4,0x0003a611,0x0003a240,0x00039e71,0x00039aa4,
 0x000396d9,0x00039310,0x00038f49,0x00038b84,0x000387c1,0x00038400,0x00038041,0x00037c84,

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?