📄 jpegqualitytestdoc.cpp
字号:
// JpegQualityTestDoc.cpp : implementation of the CJpegQualityTestDoc class
//
#include "stdafx.h"
#include "JpegQualityTest.h"
#include "JpegQualityTestDoc.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#include <Math.h>
#include "..\Defines.h"
#include "..\ImgCompress\ImgCompress.h"
#include "..\ImgDecompress\ImgDecompress.h"
#include "QualityDlg.h"
/////////////////////////////////////////////////////////////////////////////
// CJpegQualityTestDoc
IMPLEMENT_DYNCREATE(CJpegQualityTestDoc, CDocument)
BEGIN_MESSAGE_MAP(CJpegQualityTestDoc, CDocument)
//{{AFX_MSG_MAP(CJpegQualityTestDoc)
ON_COMMAND(ID_EDIT_TEST, OnEditTest)
ON_COMMAND(ID_EDIT_SEQUENCE, OnEditSequence)
ON_COMMAND(ID_EDIT_PSNR, OnEditPsnr)
ON_COMMAND(ID_EDIT_PSNRSEQUENCE, OnEditPsnrsequence)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CJpegQualityTestDoc construction/destruction
CJpegQualityTestDoc::CJpegQualityTestDoc()
{
m_pBmp=(BYTE*)::GlobalAlloc(GMEM_FIXED,MAX_BMP_SIZE);
if (!m_pBmp){
AfxMessageBox("Error to allocate memory for bitmap buffer!");
}
m_pDib=(BYTE*)::GlobalAlloc(GMEM_FIXED,MAX_BMP_SIZE);
if (!m_pDib){
AfxMessageBox("Error to allocate memory for dib buffer!");
}
m_JpegBuffer=(BYTE*)::GlobalAlloc(GMEM_FIXED,MAX_JPEG_SIZE);
if (!m_JpegBuffer){
AfxMessageBox("Error to allocate memory for jpeg buffer!");
}
m_bmInfo.bmiHeader.biBitCount=24;
m_bmInfo.bmiHeader.biClrImportant=0;
m_bmInfo.bmiHeader.biClrUsed=0;
m_bmInfo.bmiHeader.biCompression=0;
m_bmInfo.bmiHeader.biHeight=0;
m_bmInfo.bmiHeader.biPlanes=1;
m_bmInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
m_bmInfo.bmiHeader.biSizeImage=0;
m_bmInfo.bmiHeader.biWidth=0;
m_bmInfo.bmiHeader.biXPelsPerMeter=1;
m_bmInfo.bmiHeader.biYPelsPerMeter=1;
m_QualityViewDlg=NULL;
m_PsnrViewDlg=NULL;
}
CJpegQualityTestDoc::~CJpegQualityTestDoc()
{
::GlobalFree(m_pBmp);
::GlobalFree(m_pDib);
::GlobalFree(m_JpegBuffer);
if (!m_QualityViewDlg){
delete m_QualityViewDlg;
}
if (!m_PsnrViewDlg){
delete m_PsnrViewDlg;
}
}
/////////////////////////////////////////////////////////////////////////////
// CJpegQualityTestDoc serialization
void CJpegQualityTestDoc::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{
// TODO: add storing code here
}
else
{
// TODO: add loading code here
}
}
/////////////////////////////////////////////////////////////////////////////
// CJpegQualityTestDoc diagnostics
#ifdef _DEBUG
void CJpegQualityTestDoc::AssertValid() const
{
CDocument::AssertValid();
}
void CJpegQualityTestDoc::Dump(CDumpContext& dc) const
{
CDocument::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CJpegQualityTestDoc commands
BOOL CJpegQualityTestDoc::OnOpenDocument(LPCTSTR lpszPathName)
{
if (!CDocument::OnOpenDocument(lpszPathName))
return FALSE;
CFile f;
if (!f.Open(lpszPathName,CFile::modeRead)){
AfxMessageBox("Can not open file!");
return FALSE;
}
unsigned long nFileLen=f.GetLength();
if (nFileLen>MAX_BMP_SIZE){
AfxMessageBox("Image too large to this application!");
return FALSE;
}
if (f.ReadHuge(m_pBmp,nFileLen)!=nFileLen){
AfxMessageBox("Can not read from file!");
return FALSE;
}
f.Close();
if ((((BITMAPFILEHEADER*)m_pBmp)->bfType)!=((WORD)('M'<< 8)|'B')){
AfxMessageBox("Not a bitmap file!");
return FALSE;
}
if (((BITMAPINFOHEADER*)(m_pBmp+sizeof(BITMAPFILEHEADER)))->biBitCount!=24){
AfxMessageBox("Not a 24 colors bitmap file!");
return FALSE;
}
BITMAPINFOHEADER* bmih=(BITMAPINFOHEADER*)(m_pBmp+sizeof(BITMAPFILEHEADER));
m_bmInfo.bmiHeader.biWidth=bmih->biWidth;
m_bmInfo.bmiHeader.biHeight=bmih->biHeight;
for (UINT i=0;i<(nFileLen-sizeof(BITMAPFILEHEADER)-sizeof(BITMAPINFOHEADER));i++){
m_pDib[i]=150;
}
return TRUE;
}
BOOL CJpegQualityTestDoc::CompressImg(int Quality)
{
if (m_bmInfo.bmiHeader.biWidth<=0 || m_bmInfo.bmiHeader.biHeight<=0){
AfxMessageBox("Image not opened yet!");
return FALSE;
}
JPEG_CORE_PROPERTIES jcprops;
if (!ICInit(0,&jcprops)){
AfxMessageBox(ICGetLastError(0));
return FALSE;
}
int JpegSize=0;
if (!ICCompress(0,&jcprops,m_pBmp,&m_JpegBuffer,&JpegSize,Quality)){
AfxMessageBox(ICGetLastError(0));
ICRelease(0,&jcprops);
return FALSE;
}
if (!ICRelease(0,&jcprops)){
AfxMessageBox(ICGetLastError(0));
return FALSE;
}
if (!IDInit(&jcprops)){
AfxMessageBox(IDGetLastError());
return FALSE;
}
DWORD ImgWidth,ImgHeight;
if (!IDDecompress(&jcprops,m_JpegBuffer,JpegSize,&m_pDib,&ImgWidth,&ImgHeight)){
AfxMessageBox(IDGetLastError());
IDRelease(&jcprops);
return FALSE;
}
if ((DWORD)m_bmInfo.bmiHeader.biWidth!=ImgWidth || (DWORD)m_bmInfo.bmiHeader.biHeight!=ImgHeight){
AfxMessageBox("Unknown error when decompress image!");
IDRelease(&jcprops);
return FALSE;
}
if (!IDRelease(&jcprops)){
AfxMessageBox(IDGetLastError());
return FALSE;
}
return TRUE;
}
int CJpegQualityTestDoc::QualityTest()
{
if (m_bmInfo.bmiHeader.biWidth<=0 || m_bmInfo.bmiHeader.biHeight<=0){
AfxMessageBox("Image not opened yet!");
return 0;
}
BYTE* OriDib=m_pBmp+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
UINT result=0;
for (int j=0;j<m_bmInfo.bmiHeader.biHeight;j++){
for (int i=0;i<m_bmInfo.bmiHeader.biWidth;i++){
result+=abs(m_pDib[(j*m_bmInfo.bmiHeader.biWidth+i)*3]
-OriDib[(j*m_bmInfo.bmiHeader.biWidth+i)*3]
+m_pDib[(j*m_bmInfo.bmiHeader.biWidth+i)*3+1]
-OriDib[(j*m_bmInfo.bmiHeader.biWidth+i)*3+1]
+m_pDib[(j*m_bmInfo.bmiHeader.biWidth+i)*3+2]
-OriDib[(j*m_bmInfo.bmiHeader.biWidth+i)*3+2]);
}
}
return result/(m_bmInfo.bmiHeader.biWidth*m_bmInfo.bmiHeader.biHeight);
}
int CJpegQualityTestDoc::PsnrTest()
{
if (m_bmInfo.bmiHeader.biWidth<=0 || m_bmInfo.bmiHeader.biHeight<=0){
AfxMessageBox("Image not opened yet!");
return 0;
}
BYTE* OriDib=m_pBmp+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
double mse=0;
for (int j=0;j<m_bmInfo.bmiHeader.biHeight;j++){
for (int i=0;i<m_bmInfo.bmiHeader.biWidth;i++){
mse+=((m_pDib[(j*m_bmInfo.bmiHeader.biWidth+i)*3]
-OriDib[(j*m_bmInfo.bmiHeader.biWidth+i)*3]
+m_pDib[(j*m_bmInfo.bmiHeader.biWidth+i)*3+1]
-OriDib[(j*m_bmInfo.bmiHeader.biWidth+i)*3+1]
+m_pDib[(j*m_bmInfo.bmiHeader.biWidth+i)*3+2]
-OriDib[(j*m_bmInfo.bmiHeader.biWidth+i)*3+2])^2);
}
}
mse/=(m_bmInfo.bmiHeader.biWidth*m_bmInfo.bmiHeader.biHeight);
return (int)(10*log(255*255/mse));
}
void CJpegQualityTestDoc::OnEditTest()
{
CQualityDlg dlg;
if (dlg.DoModal()==IDOK){
if (CompressImg(dlg.m_Quality)){
int x=QualityTest();
CString s;
s.Format("%d",x);
AfxMessageBox(s);
UpdateAllViews(NULL);
}
}
}
void CJpegQualityTestDoc::OnEditSequence()
{
if (m_bmInfo.bmiHeader.biWidth<=0 || m_bmInfo.bmiHeader.biHeight<=0){
AfxMessageBox("Image not opened yet!");
return;
}
BeginWaitCursor();
if (!m_QualityViewDlg){
m_QualityViewDlg=new CQualityViewDlg();
m_QualityViewDlg->Create(MAKEINTRESOURCE(IDD_QUALITYVIEW_DLG),AfxGetApp()->m_pMainWnd);
CRect rect,recttmp;
m_QualityViewDlg->GetWindowRect(&rect);
AfxGetApp()->m_pMainWnd->GetWindowRect(&recttmp);
m_QualityViewDlg->MoveWindow(recttmp.right-rect.Width(),recttmp.bottom-rect.Height(),rect.Width(),rect.Height());
}
for (int i=0;i<100;i++){
m_QualityViewDlg->m_QualityDiagram[i]=CompressImg(i)?QualityTest():0;
}
m_QualityViewDlg->ShowWindow(SW_SHOW);
EndWaitCursor();
UpdateAllViews(NULL);
m_QualityViewDlg->Invalidate();
}
void CJpegQualityTestDoc::OnEditPsnr()
{
CQualityDlg dlg;
if (dlg.DoModal()==IDOK){
if (CompressImg(dlg.m_Quality)){
int x=PsnrTest();
CString s;
s.Format("%d",x);
AfxMessageBox(s);
UpdateAllViews(NULL);
}
}
}
void CJpegQualityTestDoc::OnEditPsnrsequence()
{
if (m_bmInfo.bmiHeader.biWidth<=0 || m_bmInfo.bmiHeader.biHeight<=0){
AfxMessageBox("Image not opened yet!");
return;
}
BeginWaitCursor();
if (!m_PsnrViewDlg){
m_PsnrViewDlg=new CPsnrViewDlg();
m_PsnrViewDlg->Create(MAKEINTRESOURCE(IDD_PSNRVIEW_DLG),AfxGetApp()->m_pMainWnd);
CRect rect,recttmp;
m_PsnrViewDlg->GetWindowRect(&rect);
AfxGetApp()->m_pMainWnd->GetWindowRect(&recttmp);
m_PsnrViewDlg->MoveWindow(recttmp.right-rect.Width(),recttmp.bottom-rect.Height(),rect.Width(),rect.Height());
}
for (int i=0;i<100;i++){
m_PsnrViewDlg->m_PsnrDiagram[i]=CompressImg(i)?PsnrTest():0;
}
m_PsnrViewDlg->ShowWindow(SW_SHOW);
EndWaitCursor();
UpdateAllViews(NULL);
m_PsnrViewDlg->Invalidate();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -