📄 clevels.cpp
字号:
/*
* Copyright (c) 2002-2006 Milan Cutka
*
* 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 "Clevels.h"
#include "TlevelsSettings.h"
#include "IimgFilterLevels.h"
#include "ffmpeg/libavutil/bswap.h"
//============================== TlevelsPage::TwidgetLevels =============================
LRESULT TlevelsPage::TwidgetLevels::onLbuttonDown(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
int x=GET_X_LPARAM(lParam),y=GET_Y_LPARAM(lParam);
int min=levelsPage->cfgGet(idffMin),max=levelsPage->cfgGet(idffMax);
int minP=levelsPage->bdx*min/255,maxP=levelsPage->bdx*max/255;
if (isIn(x,minP-5,minP+5)) dragIdff=idffMin;
else if (isIn(x,maxP-5,maxP+5)) dragIdff=idffMax;
else return 0;
dx=x-levelsPage->cfgGet(dragIdff)*levelsPage->bdx/255;
InvalidateRect(hwnd,NULL,FALSE);
InvalidateRect(GetDlgItem(levelsPage->m_hwnd,IDC_BMP_HISTOGRAM),NULL,FALSE);
SetCapture(hwnd);
return 0;
}
LRESULT TlevelsPage::TwidgetLevels::onMouseMove(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
if (dragIdff)
{
int x=GET_X_LPARAM(lParam);
levelsPage->cfgSet(dragIdff,255*(x-dx)/levelsPage->bdx);
levelsPage->map2dlg();
InvalidateRect(hwnd,NULL,FALSE);
InvalidateRect(GetDlgItem(levelsPage->m_hwnd,IDC_BMP_HISTOGRAM),NULL,FALSE);
return 0;
}
return TwindowWidget::onMouseMove(hwnd,uMsg,wParam,lParam);
}
LRESULT TlevelsPage::TwidgetLevels::onLbuttonUp(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
dragIdff=0;
ReleaseCapture();
InvalidateRect(GetDlgItem(levelsPage->m_hwnd,IDC_BMP_HISTOGRAM),NULL,FALSE);
return 0;
}
void TlevelsPage::TwidgetLevels::draw(LPDRAWITEMSTRUCT dis)
{
if (dragIdff)
{
HPEN pen = CreatePen(PS_DOT,0,RGB(0,0,0));
HPEN penOld = (HPEN) SelectObject(dis->hDC, pen);
COLORREF bgColor = SetBkColor(dis->hDC, RGB(255,255,255));
int x=levelsPage->cfgGet(dragIdff)*levelsPage->bdx/255;
MoveToEx(dis->hDC, x, 2, NULL);
LineTo(dis->hDC, x, dis->rcItem.bottom);
SetBkColor(dis->hDC, bgColor);
SelectObject(dis->hDC, penOld);
DeleteObject(pen);
}
}
//============================== TlevelsPage::TwidgetCurves =============================
const int TlevelsPage::TwidgetCurves::idffs[]=
{
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
};
TlevelsPage::TwidgetCurves::TwidgetCurves(HWND h,TlevelsPage *Iself):
levelsPage(Iself),
TwindowWidget(h,Iself),
h(h),
curpoint(-1),dragpoint(-1)
{
allowOwnProc();
CRect r;
GetWindowRect(h,&r);
SetWindowPos(h,NULL,0,0,r.Height(),r.Height(),SWP_NOMOVE|SWP_NOZORDER);
dxy=r.Height()+1;
load();
br=CreateSolidBrush(RGB(0,0,0));
}
TlevelsPage::TwidgetCurves::~TwidgetCurves()
{
DeleteObject(br);
}
void TlevelsPage::TwidgetCurves::load(void)
{
pt.resize(levelsPage->cfgGet(IDFF_levelsNumPoints));
for (size_t i=0;i<pt.size();i++)
{
pt[i].x=levelsPage->cfgGet(idffs[2*i+0]);
pt[i].y=levelsPage->cfgGet(idffs[2*i+1]);
}
print();
}
void TlevelsPage::TwidgetCurves::save(void)
{
levelsPage->cfgSet(IDFF_levelsNumPoints,(int)pt.size());
for (size_t i=0;i<pt.size();i++)
{
levelsPage->cfgSet(idffs[2*i+0],pt[i].x);
levelsPage->cfgSet(idffs[2*i+1],pt[i].y);
}
print();
}
void TlevelsPage::TwidgetCurves::print(void)
{
levelsPage->lbxClear(IDC_LBX_LEVELS_CURVES);
for (size_t i=0;i<pt.size();i++)
{
char_t s[30];tsprintf(s,_l("%u:[%li,%li]"),i,pt[i].x,pt[i].y);
levelsPage->lbxAdd(IDC_LBX_LEVELS_CURVES,s,i);
}
if (dragpoint!=-1)
levelsPage->lbxSetCurSel(IDC_LBX_LEVELS_CURVES,dragpoint);
}
void TlevelsPage::TwidgetCurves::draw(LPDRAWITEMSTRUCT dis)
{
for (size_t i=0;i<pt.size();i++)
{
int x=dxy*pt[i].x/256,y=dxy*(255-pt[i].y)/256;
CRect pr(x-2,y-2,x+2,y+2);
FillRect(dis->hDC,&pr,br);
}
}
std::pair<int,int> TlevelsPage::TwidgetCurves::findPoint(int sx,int sy)
{
size_t mindist=INT_MAX,mindisti=0;
for (size_t i=0;i<pt.size();i++)
{
int x=dxy*pt[i].x/256,y=dxy*(255-pt[i].y)/256;
size_t dist=sqr(x-sx)+sqr(y-sy);
if (dist<mindist)
{
mindist=dist;
mindisti=i;
if (mindist==0)
break;
}
}
return std::make_pair((int)mindist,(int)mindisti);
}
bool TlevelsPage::TwidgetCurves::setCursor(void)
{
POINT cp;
GetCursorPos(&cp);
ScreenToClient(h,&cp);
std::pair<int,int> pt=findPoint(cp.x,cp.y);
return pt.first>40?(curpoint=-1,false):(curpoint=pt.second,true);
}
LRESULT TlevelsPage::TwidgetCurves::onLbuttonDown(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
if (curpoint==-1 && pt.size()<10)
{
int x=GET_X_LPARAM(lParam),y=GET_Y_LPARAM(lParam);
x=limit_uint8(256*x/dxy);
CPoints::iterator p=pt.begin();
for (pt.begin();p!=pt.end()-1;p++)
if ((p+1)->x>x)
break;
p=pt.insert(p+1,CPoint(x,limit_uint8(255-256*y/dxy)));
save();
curpoint=int(p-pt.begin());
levelsPage->map2dlg();//InvalidateRect(hwnd,NULL,FALSE);
}
SetCapture(hwnd);SetCursor(LoadCursor(NULL,IDC_SIZEALL));
dragpoint=curpoint;
print();
return 0;
}
LRESULT TlevelsPage::TwidgetCurves::onLbuttonUp(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
dragpoint=-1;
print();
ReleaseCapture();
return 0;
}
LRESULT TlevelsPage::TwidgetCurves::onMouseMove(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
if (dragpoint!=-1)
{
int x=256*GET_X_LPARAM(lParam)/dxy;
int y=255-256*GET_Y_LPARAM(lParam)/dxy;
static const int border=40;
if (pt.size()>2 && (!isIn(x,0-border,255+border) || !isIn(y,0-border,255+border)))
{
pt.erase(pt.begin()+curpoint);
curpoint=-1;
onLbuttonUp(hwnd,uMsg,wParam,lParam);
}
else
{
pt[dragpoint].x=limit(x,int(dragpoint==0?0:pt[dragpoint-1].x),int(dragpoint==(int)pt.size()-1?255:pt[dragpoint+1].x));
pt[dragpoint].y=limit_uint8(y);
}
save();
levelsPage->map2dlg();
return 0;
}
return TwindowWidget::onMouseMove(hwnd,uMsg,wParam,lParam);
}
//===================================== TlevelsPage =====================================
void TlevelsPage::init(void)
{
deciD->queryFilterInterface(IID_IimgFilterLevels,(void**)&filter);
memset(&histogramBmp.bmiHeader,0,sizeof(histogramBmp.bmiHeader));
histogramBmp.bmiHeader.biSize=sizeof(histogramBmp.bmiHeader);
histogramBmp.bmiHeader.biWidth=256;
histogramBmp.bmiHeader.biHeight=64;
histogramBmp.bmiHeader.biPlanes=1;
histogramBmp.bmiHeader.biBitCount=8;
histogramBmp.bmiHeader.biCompression=BI_RGB;
histogramBmp.bmiHeader.biXPelsPerMeter=100;
histogramBmp.bmiHeader.biYPelsPerMeter=100;
memset(histogramBmp.bmiColors,0,256*sizeof(RGBQUAD));
histogramBmp.bmiColors[1].rgbRed=histogramBmp.bmiColors[1].rgbGreen=histogramBmp.bmiColors[1].rgbBlue=255;
histogramBmp.bmiColors[2].rgbRed=histogramBmp.bmiColors[2].rgbGreen=histogramBmp.bmiColors[2].rgbBlue=192;
memset(histogramBits,1,sizeof(histogramBits));
curvesBmp=histogramBmp;
curvesBmp.bmiHeader.biHeight=256;
hcurves=GetDlgItem(m_hwnd,IDC_BMP_LEVELS_CURVES);
bmpGradient=LoadBitmap(hi,MAKEINTRESOURCE(IDB_GRADIENT));
HDC hdc=GetDC(m_hwnd);
hdcGradient=CreateCompatibleDC(hdc);
oldHDCgradient=SelectObject(hdcGradient,bmpGradient);
LOGFONT oldFont;
HFONT hf=(HFONT)GetCurrentObject(hdc,OBJ_FONT);
GetObject(hf,sizeof(LOGFONT),&oldFont);
strcpy(oldFont.lfFaceName,_l("Courier"));
oldFont.lfWeight=FW_LIGHT;
oldFont.lfHeight=-11;
oldFont.lfWidth=0;
fontCurier=CreateFontIndirect(&oldFont);
SendMessage(GetDlgItem(m_hwnd,IDC_LBX_LEVELS_CURVES),WM_SETFONT,WPARAM(fontCurier),FALSE);
strcpy(oldFont.lfFaceName,_l("Small fonts"));
fontGradient=CreateFontIndirect(&oldFont);
ReleaseDC(m_hwnd,hdc);
isMap=false;
hIn=GetDlgItem(m_hwnd,IDC_BMP_LEVELS_IN);
hOut=GetDlgItem(m_hwnd,IDC_BMP_LEVELS_OUT);
RECT r;GetWindowRect(hIn,&r);
bdx=r.right-r.left-2;
tbrSetRange(IDC_TBR_LEVELS_GAMMA,1,400,40);
tbrSetRange(IDC_TBR_LEVELS_POSTERIZE,1,255);
startup=true;
}
void TlevelsPage::cfg2dlg(void)
{
repaint(GetDlgItem(m_hwnd,IDC_BMP_LEVELS_IN ));
repaint(GetDlgItem(m_hwnd,IDC_BMP_LEVELS_OUT));
setCheck(IDC_CHB_LEVELS_SHOW_HISTOGRAM,cfgGet(IDFF_buildHistogram));
setCheck(IDC_CHB_LEVELS_SHOW_HISTOGRAM_FULL,cfgGet(IDFF_levelsFullY));
cbxSetCurSel(IDC_CBX_LEVELS_MODE,cfgGet(IDFF_levelsMode));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -