tlevelssettings.cpp.svn-base
来自「ffshow源码」· SVN-BASE 代码 · 共 375 行
SVN-BASE
375 行
/* * 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 { double i=fullY?x:(x-16)*(255.0/219.0); double p=gamma>1?(((((pow(((i-a)/(b-a)),(1/gamma))*(d-c))+c)*i)+(i*(255-i)))/255):(((((pow(((i-a)/(b-a)),(1/gamma))*(d-c))+c)*(255-i))+(i*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 { double i=fullY?x:(x-16)*(255.0/219.0); double p=((((pow(((i-a)/(b-a)),(1/gamma))*(d-c))+c)*(sin((i/162.97466))*255))+(i*(255-(sin((i/162.97466))*255))))/255; if (!fullY) p=p*(219.0/255.0)+16.5; map[x]=limit(int(p),limitMin,limitMax); } break; case 4: gamma*=4; for (int x=0;x<256;x++) // YlevelsC { double i=fullY?x:(x-16)*(255.0/219.0); double p=((((pow(((i-a)/(b-a)),(1/gamma))*(d-c))+c)*(255-(cos((i/162.97466))*255)))+(i*(cos((i/162.97466))*255)))/255; 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 + =
减小字号Ctrl + -
显示快捷键?