⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 timgfilterlogoaway.cpp

📁 从FFMPEG转换而来的H264解码程序,VC下编译..
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*
 * Copyright (c) 2004-2006 Milan Cutka
 * Based of Logoaway plugin filter for VirtualDub by Krzysztof Wojdon
 *
 * 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 "TimgFilterLogoaway.h"
#include "TlogoawaySettings.h"

//===================================== TimgFilterLogoaway::Tplane =====================================
inline unsigned char* TimgFilterLogoaway::Tplane::getPixelAddr(int x,int y)
{
 return dst+stride2*(y>>shiftY)+(x>>shiftX);
}

unsigned char* TimgFilterLogoaway::Tplane::getCornerAddr(const TlogoawaySettings *cfg,int corner)
{
 switch (corner)
  {
   case TlogoawaySettings::NW:
    return getPixelAddr(cfg->x,cfg->y);
   case TlogoawaySettings::NE:
    return getPixelAddr(cfg->x+cfg->dx-1,cfg->y);
   case TlogoawaySettings::SW:
    return getPixelAddr(cfg->x,cfg->y+cfg->dy-1);
   case TlogoawaySettings::SE:
    return getPixelAddr(cfg->x+cfg->dx-1,cfg->y+cfg->dy-1);
   default:
    return NULL;
  }
}

void TimgFilterLogoaway::Tplane::selectPoints(const TlogoawaySettings *cfg,
                                              int bmode,
                                              unsigned char **s,unsigned char **e,
                                              int psd,int ped,
                                              int pso,int peo,
                                              int psi,int pei
                                             )
{
 switch (bmode)
  {
   case TlogoawaySettings::BM_DIRECT:
    *s=getCornerAddr(cfg,psd);
    *e=getCornerAddr(cfg,ped);
    break;
   case TlogoawaySettings::BM_OPPOSITE:
    *s=getCornerAddr(cfg,pso);
    *e=getCornerAddr(cfg,peo);
    break;
   case TlogoawaySettings::BM_INTERPOLATE:
    *s=getCornerAddr(cfg,psi);
    *e=getCornerAddr(cfg,pei);
    break;
   default:
    *s=*e=NULL;
    break;
  }
}

void TimgFilterLogoaway::Tplane::calcGradient(const unsigned char *s,const unsigned char *e,int len,FIX *r,FIX *rd)
{
 *r=*s<<16;
 *rd=(FIX(*e)-FIX(*s))<<16;
 *rd/=len-1;
}

void TimgFilterLogoaway::Tplane::createBorderH(unsigned char *border,const unsigned char *s,const unsigned char *e,int width,int bmode)
{
 int i;
 FIX rt,rd;

 switch (bmode)
  {
   case TlogoawaySettings::BM_INTERPOLATE:
    calcGradient(s,e,width,
                 &rt,
                 &rd);
    for (i=0;i<width;i++)
     {
      *border++=uint8_t(rt>>16);
      rt+=rd;
     }
    break;
   case TlogoawaySettings::BM_DIRECT:
   case TlogoawaySettings::BM_OPPOSITE:
    memcpy(border,s,width);
    break;
  }
}

void TimgFilterLogoaway::Tplane::createBorderV(unsigned char *border,const unsigned char *s,const unsigned char *e,int h,stride_t pitch,int bmode)
{
 int i;

 switch (bmode)
  {
   case TlogoawaySettings::BM_INTERPOLATE:
    {
     FIX rt,rd;
     calcGradient(s,e,h,
                  &rt,
                  &rd);
     for (i=0;i<h;i++)
      {
       *border++=uint8_t(rt>>16);
       rt+=rd;
      }
     break;
    }
   case TlogoawaySettings::BM_DIRECT:
   case TlogoawaySettings::BM_OPPOSITE:
    for (i=0;i<h;i++)
     {
      *border++=*s;
      s+=pitch;
     }
    break;
  }
}

void TimgFilterLogoaway::Tplane::createBorder(const TlogoawaySettings *cfg,int side,int bmode)
{
 unsigned char *s,*e;

 switch (side)
  {
   case TlogoawaySettings::NORTH:
    selectPoints(cfg,bmode,&s,&e,
                 TlogoawaySettings::NW,TlogoawaySettings::NE,
                 TlogoawaySettings::SW,TlogoawaySettings::SE,
                 cfg->pointnw,cfg->pointne);
    createBorderH(bordn,s,e,cfg->dx>>shiftX,bmode);
    break;
   case TlogoawaySettings::EAST:
    selectPoints(cfg,bmode,&s,&e,
                 TlogoawaySettings::NE,TlogoawaySettings::SE,
                 TlogoawaySettings::NW,TlogoawaySettings::SW,
                 cfg->pointne,cfg->pointse);
    createBorderV(borde,s,e,cfg->dy>>shiftY,stride2,bmode);
    break;
   case TlogoawaySettings::SOUTH:
    selectPoints(cfg,bmode,&s,&e,
                 TlogoawaySettings::SW,TlogoawaySettings::SE,
                 TlogoawaySettings::NW,TlogoawaySettings::NE,
                 cfg->pointsw,cfg->pointse);
    createBorderH(bords,s,e,cfg->dx>>shiftX,bmode);
    break;
   case TlogoawaySettings::WEST:
    selectPoints(cfg,bmode,&s,&e,
                 TlogoawaySettings::NW,TlogoawaySettings::SW,
                 TlogoawaySettings::NE,TlogoawaySettings::SE,
                 cfg->pointnw,cfg->pointsw);
    createBorderV(bordw,s,e,cfg->dy>>shiftY,stride2,bmode);
    break;
  }
}

void TimgFilterLogoaway::Tplane::saveLogoBorder(int border)
{
 int i;

 switch( border )
  {
   case TlogoawaySettings::NORTH:
    memcpy(logotempdata,bordn,w);
    break;
   case TlogoawaySettings::SOUTH:
    {
     unsigned char *buffer=logotempdata+logotempstride*(h-1);
     memcpy(buffer,bords,w);
     break;
    }
   case TlogoawaySettings::WEST:
    {
     unsigned char *buffer=logotempdata;
     for (i=0;i<h;i++)
      buffer[logotempstride*i]=bordw[i];
     break;
    }
   case TlogoawaySettings::EAST:
    {
     unsigned char *buffer=logotempdata;
     for (i=0;i<h;i++)
      buffer[logotempstride*i+w-1]=borde[i];
     break;
    }
  }
}

void TimgFilterLogoaway::Tplane::setAverageVH(const TlogoawaySettings *cfg)
{
 int i,j;
 int vstart,vend;
 int hstart,hend;
 FIX px,py;

 // Precalculate vertical (north->south) gradient parameters:
 // For each column: starting R,G,B and per-row deltas R,G,B
 for(i=0;i<w;i++)
  calcGradient(&bordn[i],&bords[i],h,
               &vt[i],
               &vd[i]);

 // CALCULATE RECTANGLE START AND END
 // BM_INTERPOLATE overwrites border
 // other methods do not - just leave border alone.

 if(cfg->bordn_mode==TlogoawaySettings::BM_INTERPOLATE)
  vstart=0;
 else
  vstart=1;

 if(cfg->bords_mode==TlogoawaySettings::BM_INTERPOLATE)
  vend=h;
 else
  vend=h-1;

 if(cfg->bordw_mode==TlogoawaySettings::BM_INTERPOLATE)
  hstart=0;
 else
  hstart=1;

 if(cfg->borde_mode==TlogoawaySettings::BM_INTERPOLATE)
  hend=w;
 else
  hend=w-1;

 unsigned char *pRow=logotempdata;

 // If north border unused
 // we need to skip this border with
 // one empty vertical gradient step
 if (vstart==1)
  {
   pRow+=logotempstride; // fix added on
   for (i=0;i<w;i++)
    vt[i]+=vd[i];
  }

 // Now fill logo area by walking each scanline
 // step by step through the logo h
 for (i=vstart;i<vend;i++)
  {
   int r,rd;
   // Horizontal gradient for this row
   calcGradient(&bordw[i],&borde[i],w,&r,&rd);

   if (hstart==1) // First column step skip
    r+=rd;

   // Make whole logo row
   for (j=hstart;j<hend;j++)
    {
     // Update vertical gradient current component
     // Next row we will need next vertical step
     vt[j]+=vd[j];
     // Make weighted H gradient component
     px=r*(10-cfg->vhweight);
     // Make weighted V gradient component
     py=vt[j]*cfg->vhweight;
     // Calc
     pRow[j]=uint8_t(((px+py)/10)>>16);
     // Next pixel, one gradient step
     r+=rd;
    }
    // Get next row start Real UP->DOWN, not VirtualDub down->up
   pRow+=logotempstride;
  }
}

void TimgFilterLogoaway::Tplane::blurLogotemp(bool useparambitmap)
{
 unsigned char *rowp, *row, *rown;
 unsigned char *rowbkup;

 rowp   =(unsigned char*)_alloca(w);
 rowbkup=(unsigned char*)_alloca(w);

 memcpy(rowp,logotempdata,w);

 row=logotempdata+logotempstride;
 rown=row+logotempstride;

 for (int i=1;i<=h-2;i++)
  {
   // 1 ... X+
   memcpy(rowbkup,row,w);
   for (int j=1;j<=w-2;j++)
    if (!useparambitmap ||
       (parambitmapdata[i*parambitmapstride+j]>SHAPEMAP_NOCHANGE &&
        parambitmapdata[i*parambitmapstride+j]<SHAPEMAP_CONTOUR))
      {
       int r=rowp[j-1]+
             rowp[j+1]+
             (row[j]<<2)+
             rown[j-1]+
             rown[j+1];
       row[j]=uint8_t(r/8);
      }
   row=rown;
   rown=rown+logotempstride;
   memcpy(rowp,rowbkup,w);
  }
}

void TimgFilterLogoaway::Tplane::calcUweWeightTable(int w,int h,int power)
{
 double e = 1.0 + (0.3 * power);
 int x;
 for (x=0;x<w;x++)
  for (int y=0;y<h;y++)
   if(x+y!=0)
    {
     double d=pow(sqrt(double(x*x+y*y)),e);
     uwetable[x+y*w]=1.0/d;
    }
   else
    uwetable[x+y*w]=1.0;

 for (x=1;x<w-1;x++)
  for (int y=1;y<h-1;y++)
   {
    double weightsum=0;
    for (int bx=0;bx<w;bx++)
     {
      weightsum+=uwetable[abs(bx-x)+y*w];
      weightsum+=uwetable[abs(bx-x)+abs(h-1-y)*w];
     }
    for (int by=1;by<h-1;by++)
     {
      weightsum+=uwetable[x+abs(by-y)*w];
      weightsum+=uwetable[abs(w-1-x)+abs(by-y)*w];
     }
    uweweightsum[y*w+x]=weightsum;
   }
}

void TimgFilterLogoaway::Tplane::uwe(const TlogoawaySettings *cfg)
{
 if (!uwetable)
  {
   uwetable=(double*)aligned_malloc(w*h*sizeof(double));
   uweweightsum=(double*)aligned_malloc(w*h*sizeof(double));
   calcUweWeightTable(w,h,cfg->blur);
  }

 for (int x=1;x<w-1;x++)
  for (int y=1;y<h-1;y++)
   {
    double r=0;
    const unsigned char *lineN=bordn,*lineS=bords;
    for (int bx=0;bx<w;bx++)
     {
      r+=lineN[bx]*uwetable[abs(bx-x)+y*w];
      r+=lineS[bx]*uwetable[abs(bx-x)+abs(h-1-y)*w];
     }
    const unsigned char *lineW=bordw,*lineE=borde;
    for (int by=1;by<h-1;by++)
     {
      r+=lineW[by]*uwetable[x+abs(by-y)*w];
      r+=lineE[by]*uwetable[abs(w-1-x)+abs(by-y)*w];
     }

⌨️ 快捷键说明

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