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

📄 tlevelssettings.cpp

📁 从FFMPEG转换而来的H264解码程序,VC下编译..
💻 CPP
字号:
/*
 * Copyright (c) 2003-2006 Milan Cutka
 *
 * curve calculation from The GIMP -- an image manipulation program Copyright (C) 1995 Spencer Kimball and Peter Mattis
 *
 * 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 "TlevelsSettings.h"
#include "TimgFilterLevels.h"
#include "Clevels.h"
#include "TffdshowPageDec.h"

const char_t* TlevelsSettings::modes[]=
{
 _l("original"),
 _l("Didee's Ylevels"), //TODO: revert to Did閑 when unicode
 _l("Didee's YlevelsG"),
 _l("Didee's YlevelsS"),
 _l("Didee's YlevelsC"),
 _l("curve"),
 NULL
};

const TlevelsSettings::CRPoint TlevelsSettings::points[10]={&TlevelsSettings::point0x,&TlevelsSettings::point0y,&TlevelsSettings::point1x,&TlevelsSettings::point1y,&TlevelsSettings::point2x,&TlevelsSettings::point2y,&TlevelsSettings::point3x,&TlevelsSettings::point3y,&TlevelsSettings::point4x,&TlevelsSettings::point4y,&TlevelsSettings::point5x,&TlevelsSettings::point5y,&TlevelsSettings::point6x,&TlevelsSettings::point6y,&TlevelsSettings::point7x,&TlevelsSettings::point7y,&TlevelsSettings::point8x,&TlevelsSettings::point8y,&TlevelsSettings::point9x,&TlevelsSettings::point9y};

void TlevelsSettings::calcMap(unsigned int map[256],int *divisor)
{
 calcMap(map,divisor,inMin,inMax);
}
void TlevelsSettings::calcMap(unsigned int map[256],int *divisor,int inMin,int inMax)
{
 double a=inMin,b=inMax,c=outMin,d=outMax;if (a==b) b+=1;if (c==d) d+=1;
 double gamma=this->gamma/100.0;
 *divisor=inMax-inMin+(inMax==inMin);
 int limitMin=fullY?0:16,limitMax=fullY?255:235;
 switch (mode)
  {
   case 0:
    for (int x=0;x<256;x++) // original
     {
      double i=fullY?x:(x-16)*(255.0/219.0);
      double p=(i-inMin)/(*divisor);
      p=pow(limit(p,0.0,1.0),1/gamma);
      p=p*(outMax-outMin)+outMin;
      map[x]=limit(int(p),limitMin,limitMax);
     }
   case 1:
    for (int x=0;x<256;x++) // Ylevels
     {
      double i=fullY?x:(x-16)*(255.0/219.0);
      double p=pow((i-a)/(b-a),1/gamma)*(d-c)+c;
      if (!fullY) p=p*(219.0/255.0)+16.5;
      map[x]=limit(int(p),limitMin,limitMax);
     }
    break;
   case 2:
    for (int x=0;x<256;x++) // YlevelsG
     // Original script for Avisynth by Didee and Alain2
     // http://forum.doom9.org/showthread.php?p=897854
     //
     // Function YlevelsG_DarkEnh(clip clp, int a, float gamma, int b, int c, int d)
     // {
     //  wicked = "x "+string(a)+" - "+string(b)+" "+string(a)+" - / "+string(d)+" "+string(c)+" - * "+string(c)+" + x 255 / * x "+string(a)+" - "+string(b)+" "+string(a)+" - / 1 "+string(gamma)+" / ^ "+string(d)+" "+string(c)+" - * "+string(c)+" + 1 x 255 / - * +"
     //  Return( clp.mt_lut(Yexpr = wicked, U=2,V=2) )
     // }
     {
      double i=fullY?x:(x-16)*(255.0/219.0);
      double p=((i-a)/(b-a)*(d-c)+c)*i/255+(pow((i-a)/(b-a),1/gamma)*(d-c)+c)*(1-i/255);
      if (!fullY) p=p*(219.0/255.0)+16.5;
      map[x]=limit(int(p),limitMin,limitMax);
     }
    break;
   case 3:
    for (int x=0;x<256;x++) // YlevelsS
     // Original script for Avisynth by Didee and Alain2
     //
     // Function YlevelsS_DarkEnh(clip clp, int a, float gamma, int b, int c, int d)
     // {
     //  wicked = "x "+string(a)+" - "+string(b)+" "+string(a)+" - / "+string(d)+" "+string(c)+" - * "+string(c)+" + x 162.338 / sin * x "+string(a)+" - "+string(b)+" "+string(a)+" - / 1 "+string(gamma)+" / ^ "+string(d)+" "+string(c)+" - * "+string(c)+" + 1 x 162.338 / sin - * +"
     //  Return( clp.mt_lut(Yexpr = wicked, U=2,V=2) )
     // }
     {
      double i=fullY?x:(x-16)*(255.0/219.0);
      double p=((i-a)/(b-a)*(d-c)+c)*sin(i/162.338)+(pow((i-a)/(b-a),1/gamma)*(d-c)+c)*(1-sin(i/162.338));
      if (!fullY) p=p*(219.0/255.0)+16.5;
      map[x]=limit(int(p),limitMin,limitMax);
     }
    break;
   case 4:
    for (int x=0;x<256;x++) // YlevelsC
     // Original script for Avisynth by Didee and Alain2
     //
     // Function YlevelsC_DarkEnh(clip clp, int a, float gamma, int b, int c, int d)
     // {
     //  wicked = "x "+string(a)+" - "+string(b)+" "+string(a)+" - / "+string(d)+" "+string(c)+" - * "+string(c)+" + 1 x 162.338 / cos - * x "+string(a)+" - "+string(b)+" "+string(a)+" - / 1 "+string(gamma)+" / ^ "+string(d)+" "+string(c)+" - * "+string(c)+" + x 162.338 / cos * +"
     //  Return( clp.mt_lut(Yexpr = wicked, U=2,V=2) )
     // }
     {
      double i=fullY?x:(x-16)*(255.0/219.0);
      double p=((i-a)/(b-a)*(d-c)+c)*(1-cos(i/162.338))+(pow((i-a)/(b-a),1/gamma)*(d-c)+c)*cos(i/162.338);
      if (!fullY) p=p*(219.0/255.0)+16.5;
      map[x]=limit(int(p),limitMin,limitMax);
     }
    break;
   case 5:
    calcCurve(map);
    break;
  }
 if (mode!=5 && posterize!=255)
  {
   unsigned int stepd=256/(posterize-1);
   for (unsigned int x=0;x<256;x++)
    map[x]=limit(((map[x]+stepd/2)/stepd)*stepd,0U,255U);
  }
}

void TlevelsSettings::calcCurve(unsigned int dp[256])
{
 for (int x=0;x<this->*points[0][0];x++)
  dp[x]=this->*points[0][1];
 for (int i=0;i<numPoints-1;i++)
  {
   int p1 = i==0?i:i-1;
   int p2 = i;
   int p3 = i+1;
   int p4 = i==numPoints-2?numPoints-1:i+2;
   plot_curve(p1,p2,p3,p4,dp);
  }
 for (int x=this->*points[numPoints-1][0];x<256;x++)
  dp[x]=this->*points[numPoints-1][1];
 for (int i=0;i<numPoints;i++)
  dp[this->*points[i][0]]=this->*points[i][1];
}

void TlevelsSettings::plot_curve(int p1,int p2,int p3,int p4,unsigned int curve[256])
{
 typedef double CRMatrix[4][4];
 static const CRMatrix CR_basis=
  {
   { -0.5,  1.5, -1.5,  0.5 },
   {  1.0, -2.5,  2.0, -0.5 },
   { -0.5,  0.0,  0.5,  0.0 },
   {  0.0,  1.0,  0.0,  0.0 },
  };
 struct curves_CR_compose
  {
   void operator ()(const CRMatrix &a, const CRMatrix &b, CRMatrix &ab)
    {
     for (int i = 0; i < 4; i++)
      for (int j = 0; j < 4; j++)
       ab[i][j] = (a[i][0] * b[0][j] +
                   a[i][1] * b[1][j] +
                   a[i][2] * b[2][j] +
                   a[i][3] * b[3][j]);
    }
  };

 CRMatrix geometry;
 CRMatrix tmp1, tmp2;
 CRMatrix deltas;
 double  x, dx, dx2, dx3;
 double  y, dy, dy2, dy3;
 double  d, d2, d3;
 int     lastx, lasty;
 int   newx, newy;
 int     i;

 /* construct the geometry matrix from the segment */
 for (i = 0; i < 4; i++)
  {
   geometry[i][2] = 0;
   geometry[i][3] = 0;
  }

 for (i = 0; i < 2; i++)
  {
   geometry[0][i] = this->*points[p1][i];
   geometry[1][i] = this->*points[p2][i];
   geometry[2][i] = this->*points[p3][i];
   geometry[3][i] = this->*points[p4][i];
  }

 /* subdivide the curve */
 static const int CURVES_SUBDIVIDE=1000;

 d = 1.0 / CURVES_SUBDIVIDE;
 d2 = d * d;
 d3 = d * d * d;

 /* construct a temporary matrix for determining the forward
  * differencing deltas
  */
 tmp2[0][0] = 0;       tmp2[0][1] = 0;       tmp2[0][2] = 0;  tmp2[0][3] = 1;
 tmp2[1][0] = d3;      tmp2[1][1] = d2;      tmp2[1][2] = d;  tmp2[1][3] = 0;
 tmp2[2][0] = 6 * d3;  tmp2[2][1] = 2 * d2;  tmp2[2][2] = 0;  tmp2[2][3] = 0;
 tmp2[3][0] = 6 * d3;  tmp2[3][1] = 0;       tmp2[3][2] = 0;  tmp2[3][3] = 0;

 /* compose the basis and geometry matrices */
 curves_CR_compose()(CR_basis, geometry, tmp1);

 /* compose the above results to get the deltas matrix */
 curves_CR_compose()(tmp2, tmp1, deltas);

 /* extract the x deltas */
 x   = deltas[0][0];
 dx  = deltas[1][0];
 dx2 = deltas[2][0];
 dx3 = deltas[3][0];

 /* extract the y deltas */
 y   = deltas[0][1];
 dy  = deltas[1][1];
 dy2 = deltas[2][1];
 dy3 = deltas[3][1];

 lastx = limit_uint8((int)x);
 lasty = limit_uint8((int)y);

 curve[lastx] = lasty;

 /* loop over the curve */
 for (i = 0; i < CURVES_SUBDIVIDE; i++)
  {
   /* increment the x values */
   x += dx;
   dx += dx2;
   dx2 += dx3;

   /* increment the y values */
   y += dy;
   dy += dy2;
   dy2 += dy3;

   newx = limit_uint8 (int (x));
   newy = limit_uint8 (int (y));

   /* if this point is different than the last one...then draw it */
   if ((lastx != newx) || (lasty != newy))
    curve[newx] = newy;

   lastx = newx;
   lasty = newy;
  }
}

const TfilterIDFF TlevelsSettings::idffs=
{
 /*name*/      _l("Levels"),
 /*id*/        IDFF_filterLevels,
 /*is*/        IDFF_isLevels,
 /*order*/     IDFF_orderLevels,
 /*show*/      IDFF_showLevels,
 /*full*/      IDFF_fullLevels,
 /*half*/      IDFF_halfLevels,
 /*dlgId*/     IDD_LEVELS,
};

TlevelsSettings::TlevelsSettings(TintStrColl *Icoll,TfilterIDFFs *filters):TfilterSettingsVideo(sizeof(*this),Icoll,filters,&idffs)
{
 static const TintOptionT<TlevelsSettings> iopts[]=
  {
   IDFF_isLevels       ,&TlevelsSettings::is      ,0,0,_l(""),1,
     _l("isLevels"),0,
   IDFF_showLevels     ,&TlevelsSettings::show    ,0,0,_l(""),1,
     _l("showLevels"),1,
   IDFF_orderLevels    ,&TlevelsSettings::order   ,1,1,_l(""),1,
     _l("orderLevels"),0,
   IDFF_fullLevels     ,&TlevelsSettings::full    ,0,0,_l(""),1,
     _l("fullLevels"),0,
   IDFF_halfLevels     ,&TlevelsSettings::half    ,0,0,_l(""),1,
     _l("halfLevels"),0,
   IDFF_levelsMode     ,&TlevelsSettings::mode    ,0,5,_l(""),1,
     _l("levelsMode"),0,
   IDFF_levelsGamma    ,&TlevelsSettings::gamma   ,1,400,_l(""),1,
     _l("levelsGamma"),100,
   IDFF_levelsPosterize,&TlevelsSettings::posterize,2,255,_l(""),1,
     _l("levelsPosterize"),255,
   IDFF_levelsInMin    ,&TlevelsSettings::inMin   ,-3,-3,_l(""),1,
     _l("levelsInMin"),0,
   IDFF_levelsInMax    ,&TlevelsSettings::inMax   ,-3,-3,_l(""),1,
     _l("levelsInMax"),255,
   IDFF_levelsOutMin   ,&TlevelsSettings::outMin  ,-3,-3,_l(""),1,
     _l("levelsOutMin"),0,
   IDFF_levelsOutMax   ,&TlevelsSettings::outMax  ,-3,-3,_l(""),1,
     _l("levelsOutMax"),255,
   IDFF_levelsOnlyLuma ,&TlevelsSettings::onlyLuma,0,0,_l(""),1,
     _l("levelsOnlyLuma"),0,
   IDFF_levelsFullY    ,&TlevelsSettings::fullY   ,0,0,_l(""),1,
     _l("levelsFullY"),0,
   IDFF_levelsInAuto   ,&TlevelsSettings::inAuto  ,0,0,_l(""),1,
     _l("levelsInAuto"),0,

   IDFF_levelsNumPoints,&TlevelsSettings::numPoints ,2,10,_l(""),1,
     _l("levelsNumPoints"),2,
   IDFF_levelsPoint0x  ,&TlevelsSettings::point0x   ,0,255,_l(""),1,
     _l("levelsPoint0x"),0,
   IDFF_levelsPoint0y  ,&TlevelsSettings::point0y   ,0,255,_l(""),1,
     _l("levelsPoint0y"),0,
   IDFF_levelsPoint1x  ,&TlevelsSettings::point1x   ,0,255,_l(""),1,
     _l("levelsPoint1x"),255,
   IDFF_levelsPoint1y  ,&TlevelsSettings::point1y   ,0,255,_l(""),1,
     _l("levelsPoint1y"),255,
   IDFF_levelsPoint2x  ,&TlevelsSettings::point2x   ,0,255,_l(""),1,
     _l("levelsPoint2x"),0,
   IDFF_levelsPoint2y  ,&TlevelsSettings::point2y   ,0,255,_l(""),1,
     _l("levelsPoint2y"),0,
   IDFF_levelsPoint3x  ,&TlevelsSettings::point3x   ,0,255,_l(""),1,
     _l("levelsPoint3x"),0,
   IDFF_levelsPoint3y  ,&TlevelsSettings::point3y   ,0,255,_l(""),1,
     _l("levelsPoint3y"),0,
   IDFF_levelsPoint4x  ,&TlevelsSettings::point4x   ,0,255,_l(""),1,
     _l("levelsPoint4x"),0,
   IDFF_levelsPoint4y  ,&TlevelsSettings::point4y   ,0,255,_l(""),1,
     _l("levelsPoint4y"),0,
   IDFF_levelsPoint5x  ,&TlevelsSettings::point5x   ,0,255,_l(""),1,
     _l("levelsPoint5x"),0,
   IDFF_levelsPoint5y  ,&TlevelsSettings::point5y   ,0,255,_l(""),1,
     _l("levelsPoint5y"),0,
   IDFF_levelsPoint6x  ,&TlevelsSettings::point6x   ,0,255,_l(""),1,
     _l("levelsPoint6x"),0,
   IDFF_levelsPoint6y  ,&TlevelsSettings::point6y   ,0,255,_l(""),1,
     _l("levelsPoint6y"),0,
   IDFF_levelsPoint7x  ,&TlevelsSettings::point7x   ,0,255,_l(""),1,
     _l("levelsPoint7x"),0,
   IDFF_levelsPoint7y  ,&TlevelsSettings::point7y   ,0,255,_l(""),1,
     _l("levelsPoint7y"),0,
   IDFF_levelsPoint8x  ,&TlevelsSettings::point8x   ,0,255,_l(""),1,
     _l("levelsPoint8x"),0,
   IDFF_levelsPoint8y  ,&TlevelsSettings::point8y   ,0,255,_l(""),1,
     _l("levelsPoint8y"),0,
   IDFF_levelsPoint9x  ,&TlevelsSettings::point9x   ,0,255,_l(""),1,
     _l("levelsPoint9x"),0,
   IDFF_levelsPoint9y  ,&TlevelsSettings::point9y   ,0,255,_l(""),1,
     _l("levelsPoint9y"),0,

   0
  };
 addOptions(iopts);

 static const TcreateParamList1 listMode(modes);setParamList(IDFF_levelsMode,&listMode);
}

void TlevelsSettings::getMinMax(int id,int &min,int &max)
{
 switch (id)
  {
   case IDFF_levelsInMin :min=0;max=inMax-1;break;
   case IDFF_levelsInMax :min=inMin+1;max=255;break;
   case IDFF_levelsOutMin:min=0;max=outMax-1;break;
   case IDFF_levelsOutMax:min=outMin+1;max=255;break;
  }
}

void TlevelsSettings::createFilters(size_t filtersorder,Tfilters *filters,TfilterQueue &queue) const
{
 idffOnChange(idffs,filters,queue.temporary);
 if (show)
  queueFilter<TimgFilterLevels>(filtersorder,filters,queue);
}
void TlevelsSettings::createPages(TffdshowPageDec *parent) const
{
 parent->addFilterPage<TlevelsPage>(&idffs);
}

const int* TlevelsSettings::getResets(unsigned int pageId)
{
 static const int idResets[]={
  IDFF_levelsMode,IDFF_levelsOnlyLuma,IDFF_levelsFullY,
  IDFF_levelsInMin,IDFF_levelsInMax,IDFF_levelsInAuto,IDFF_levelsOutMin,IDFF_levelsOutMax,IDFF_levelsGamma,IDFF_levelsPosterize,
  IDFF_levelsNumPoints,IDFF_levelsPoint0x,IDFF_levelsPoint0y,IDFF_levelsPoint1x,IDFF_levelsPoint1y,IDFF_levelsPoint2x,IDFF_levelsPoint2y,IDFF_levelsPoint3x,IDFF_levelsPoint3y,IDFF_levelsPoint4x,IDFF_levelsPoint4y,IDFF_levelsPoint5x,IDFF_levelsPoint5y,IDFF_levelsPoint6x,IDFF_levelsPoint6y,IDFF_levelsPoint7x,IDFF_levelsPoint7y,IDFF_levelsPoint8x,IDFF_levelsPoint8y,IDFF_levelsPoint9x,IDFF_levelsPoint9y,
  0};
 return idResets;
}

bool TlevelsSettings::getTip(unsigned int pageId,char_t *tipS,size_t len)
{
 tsnprintf(tipS,len,_l("%s\nInput min: %i, input max: %i, output min:%i, output max:%i\nGamma correction: %5.2f"),modes[mode],inMin,inMax,outMin,outMax,gamma/100.0f);
 if (posterize!=255)
  strncatf(tipS,len,_l("\nPosterizing to %i levels"),posterize);
 return true;
}

⌨️ 快捷键说明

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