?? dlgarith.cpp
字號:
/////////////////////////////////////////////////////////////////////////////
// CDlgArith dialog
#include "stdafx.h"
#include "ImageProcessing.h"
#include "DlgCoding.h"
#include <math.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define fPro4Zero 0.25;
#define fPro4One 0.75;
CDlgArith::CDlgArith(CWnd* pParent /*=NULL*/)
: CDialog(CDlgArith::IDD, pParent)
{
//{{AFX_DATA_INIT(CDlgArith)
m_ArithSerial = _T("");
m_ArithOutput = _T("");
m_ArithDecode = _T("");
//}}AFX_DATA_INIT
}
void CDlgArith::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CDlgArith)
DDX_Control(pDX, IDC_EDIT1, m_ConArithSer);
DDX_Control(pDX, IDCODING, m_coding);
DDX_Control(pDX, IDDECODING, m_decoding);
DDX_Text(pDX, IDC_EDIT1, m_ArithSerial);
DDV_MaxChars(pDX, m_ArithSerial, 15);
DDX_Text(pDX, IDC_EDIT2, m_ArithOutput);
DDX_Text(pDX, IDC_EDIT4, m_ArithDecode);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CDlgArith, CDialog)
//{{AFX_MSG_MAP(CDlgArith)
ON_BN_CLICKED(IDDECODING, OnDecoding)
ON_BN_CLICKED(IDCODING, OnCoding)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDlgArith message handlers
//void CDlgArith::OnOK()
//{
// CDialog::OnOK();
//}
///////////////////////////////////////////////////////////////
// DlgCodingIArith dialog
/***********************************************************
實現對已經編碼的碼字進行解碼的功能
*********************************************************
*/
void CDlgArith::OnDecoding()
{
// 二值序列的長度
int nOutLength;
// 算術編碼的長度
int nInLength;
// 編碼區間的上限和下限
double dHigh=1.0;
double dLow=0.0;
// 編碼區間的長度
double dRange=1.0;
// 判斷二值序列是否全零
int nNo1=0;
// 循環變量
int i;
// 二進制表示為十進制
double dTenCode=0;
// 中間變量
double d2Pow;
double dTemp;
// 接收數據
UpdateData(TRUE);
// 解碼顯示清空
m_ArithDecode = _T("");
// 顯示數據
UpdateData(FALSE);
// 算術編碼的長度
nInLength =m_ArithOutput.GetLength();
// 將二進制序列轉化為十進制,并判斷是否為零
for (i=0; i<nInLength;i++ )
{
// 二進制的每位對應十進制的值
d2Pow = pow(0.5,i+1);
if(m_ArithOutput.Mid(i,1)=='1')
{
dTenCode=dTenCode+d2Pow;
nNo1++;
}
}
// 二值序列的長度
nOutLength = m_ArithSerial.GetLength();
// 分全零和非全零兩種情況解碼
if(nNo1!=0)
{
for(i=0;i<nOutLength;i++)
{
dTemp=dLow+dRange*fPro4Zero;
if(dTemp>dTenCode)
{
// 輸出0
m_ArithDecode=m_ArithDecode+'0';
// 編碼區間上下限的計算
dLow=dLow;
dHigh=dLow+dRange*fPro4Zero;
// 區間范圍
dRange=dHigh-dLow;
}
else
{
// 輸出1
m_ArithDecode=m_ArithDecode+'1';
// 編碼區間上下限的計算
dLow=dLow+dRange*fPro4Zero;
dHigh=dHigh;
// 區間范圍
dRange=dHigh-dLow;
}
}
}
else
{
for(i=0;i<nOutLength;i++)
m_ArithDecode=m_ArithDecode+'1';
}
// 數據輸出更新
UpdateData(FALSE);
// 在重新輸入編碼前不允許輸入
m_decoding.EnableWindow(FALSE);
// 允許輸入
m_ConArithSer.EnableWindow(TRUE);
// 允許解碼
m_coding.EnableWindow(TRUE);
}
/***********************************************************
實現對輸入二進制序列進行編碼的功能
*********************************************************
*/
void CDlgArith::OnCoding()
{
// 輸入二值序列長度
int nInLength;
// 輸出碼字長度
int nOutLength;
// 循環變量
int i;
// 中間變量
double dTemp;
// 編碼區間的上限和下限
double dHigh=1.0;
double dLow=0.0;
// 編碼區間的長度
double dRange=1.0;
// 累積概率
double dAccuPro=1.0;
// 接收輸入的數據
UpdateData(TRUE);
// 清除輸出的編碼碼字
m_ArithOutput = _T("");
// 輸出
UpdateData(FALSE);
// 令編碼按鈕無效
m_decoding.EnableWindow(FALSE);
// 輸入的二值序列長度
nInLength = m_ArithSerial.GetLength();
// 對二值序列進行編碼
for (i = 0; i < nInLength; i++ )
{
// 如果輸入為1
if(m_ArithSerial.Mid(i,1) == "1")
{
// 編碼區間上下限的計算
dHigh = dHigh;
dLow = dLow + dRange*fPro4Zero;
// 編碼區間長度
dRange = dHigh - dLow;
// 二值序列出現概率的計算
dAccuPro = dAccuPro * fPro4One;
}
// 如果輸入為0
else if(m_ArithSerial.Mid(i,1) == "0")
{
// 編碼區間上下限的計算
dHigh = dLow + dRange*fPro4Zero;
dLow = dLow;
// 編碼區間長度
dRange = dHigh - dLow;
// 二值序列出現概率的計算
dAccuPro = dAccuPro * fPro4Zero;
}
// 如果輸入非二值序列
else
{
// 重新輸入
MessageBox("請輸入二值序列!", "系統提示" ,
MB_ICONINFORMATION | MB_OK);
return;
}
}
// 計算輸出碼字的長度
dTemp = floor( -log10(dAccuPro) / log10(2) ) + 1;
nOutLength = (int)dTemp;
dTemp = dLow;
double d2Pow;
// 將十進制的小數轉化成二進制的小數表示
for (i = 0; i < nOutLength; i++ )
{
// 二進制小數第i對應的十進制值
d2Pow = pow(0.5,i + 1);
// 判斷當前位賦值0或者1
if(dTemp >= d2Pow)
{
m_ArithOutput = m_ArithOutput + "1";
dTemp = dTemp - d2Pow;
}
else
m_ArithOutput = m_ArithOutput + "0";
}
// 轉化后是否有余數
if(dTemp > 0)
{
// 二進制小數進行進位
for(i = nOutLength-1; i >= 0; i--)
{
// 進位,1轉化為0
if(m_ArithOutput.Mid(i,1) == '1')
{
m_ArithOutput.Delete(i,1);
m_ArithOutput.Insert(i,"0");
}
// 進位完成,最后的0位轉化為1
else
{
m_ArithOutput.Delete(i,1);
m_ArithOutput.Insert(i,"1");
break;
}
}
}
// 編碼完成,數據更新
UpdateData(FALSE);
// 允許進行解碼
m_decoding.EnableWindow(TRUE);
// 解碼前禁止編碼
m_coding.EnableWindow(FALSE);
// 解碼前禁止輸入新的二進制序列
m_ConArithSer.EnableWindow(FALSE);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -