DlgArith.cpp
上传用户:panpan8800
上传日期:2013-06-29
资源大小:274k
文件大小:6k
源码类别:

图形图像处理

开发平台:

Visual C++

  1. /////////////////////////////////////////////////////////////////////////////
  2. // CDlgArith dialog
  3. #include "stdafx.h"
  4. #include "ImageProcessing.h"
  5. #include "DlgCoding.h"
  6. #include <math.h>
  7. #ifdef _DEBUG
  8. #define new DEBUG_NEW
  9. #undef THIS_FILE
  10. static char THIS_FILE[] = __FILE__;
  11. #endif
  12. #define fPro4Zero  0.25;
  13. #define fPro4One   0.75;
  14. CDlgArith::CDlgArith(CWnd* pParent /*=NULL*/)
  15. : CDialog(CDlgArith::IDD, pParent)
  16. {
  17. //{{AFX_DATA_INIT(CDlgArith)
  18. m_ArithSerial = _T("");
  19. m_ArithOutput = _T("");
  20. m_ArithDecode = _T("");
  21. //}}AFX_DATA_INIT
  22. }
  23. void CDlgArith::DoDataExchange(CDataExchange* pDX)
  24. {
  25. CDialog::DoDataExchange(pDX);
  26. //{{AFX_DATA_MAP(CDlgArith)
  27. DDX_Control(pDX, IDC_EDIT1, m_ConArithSer);
  28. DDX_Control(pDX, IDCODING, m_coding);
  29. DDX_Control(pDX, IDDECODING, m_decoding);
  30. DDX_Text(pDX, IDC_EDIT1, m_ArithSerial);
  31. DDV_MaxChars(pDX, m_ArithSerial, 15);
  32. DDX_Text(pDX, IDC_EDIT2, m_ArithOutput);
  33. DDX_Text(pDX, IDC_EDIT4, m_ArithDecode);
  34. //}}AFX_DATA_MAP
  35. }
  36. BEGIN_MESSAGE_MAP(CDlgArith, CDialog)
  37. //{{AFX_MSG_MAP(CDlgArith)
  38. ON_BN_CLICKED(IDDECODING, OnDecoding)
  39. ON_BN_CLICKED(IDCODING, OnCoding)
  40. //}}AFX_MSG_MAP
  41. END_MESSAGE_MAP()
  42. /////////////////////////////////////////////////////////////////////////////
  43. // CDlgArith message handlers
  44. //void CDlgArith::OnOK() 
  45. //{
  46. // CDialog::OnOK();
  47. //}
  48. ///////////////////////////////////////////////////////////////
  49. // DlgCodingIArith dialog
  50. /***********************************************************
  51.  实现对已经编码的码字进行解码的功能
  52.  *********************************************************
  53. */
  54. void CDlgArith::OnDecoding() 
  55. {
  56. // 二值序列的长度
  57. int nOutLength;
  58. // 算术编码的长度
  59. int nInLength;
  60. // 编码区间的上限和下限  
  61. double dHigh=1.0;
  62. double dLow=0.0;
  63. // 编码区间的长度
  64. double dRange=1.0;
  65. // 判断二值序列是否全零
  66. int nNo1=0;
  67. // 循环变量
  68. int i;
  69. // 二进制表示为十进制
  70. double dTenCode=0;
  71. // 中间变量
  72. double d2Pow;
  73. double dTemp;
  74. // 接收数据
  75. UpdateData(TRUE);
  76. // 解码显示清空
  77. m_ArithDecode = _T("");
  78. // 显示数据
  79. UpdateData(FALSE);
  80. // 算术编码的长度
  81. nInLength =m_ArithOutput.GetLength();
  82. // 将二进制序列转化为十进制,并判断是否为零
  83. for (i=0; i<nInLength;i++ )
  84. {
  85. // 二进制的每位对应十进制的值
  86. d2Pow = pow(0.5,i+1);
  87. if(m_ArithOutput.Mid(i,1)=='1')
  88. {
  89. dTenCode=dTenCode+d2Pow;
  90. nNo1++;
  91. }
  92. }
  93. // 二值序列的长度
  94. nOutLength = m_ArithSerial.GetLength();
  95. // 分全零和非全零两种情况解码
  96. if(nNo1!=0)
  97. {
  98. for(i=0;i<nOutLength;i++)
  99. {
  100. dTemp=dLow+dRange*fPro4Zero;
  101. if(dTemp>dTenCode)
  102. {
  103. // 输出0
  104. m_ArithDecode=m_ArithDecode+'0';
  105. // 编码区间上下限的计算
  106. dLow=dLow;
  107. dHigh=dLow+dRange*fPro4Zero;
  108. // 区间范围
  109. dRange=dHigh-dLow;
  110. }
  111. else
  112. {
  113. // 输出1
  114. m_ArithDecode=m_ArithDecode+'1';
  115. // 编码区间上下限的计算
  116. dLow=dLow+dRange*fPro4Zero;
  117. dHigh=dHigh;
  118. // 区间范围
  119. dRange=dHigh-dLow;
  120. }
  121. }
  122. }
  123. else
  124. {
  125. for(i=0;i<nOutLength;i++)
  126. m_ArithDecode=m_ArithDecode+'1';
  127. }
  128. // 数据输出更新
  129. UpdateData(FALSE);
  130. // 在重新输入编码前不允许输入
  131. m_decoding.EnableWindow(FALSE);
  132. // 允许输入
  133. m_ConArithSer.EnableWindow(TRUE);
  134. // 允许解码
  135. m_coding.EnableWindow(TRUE);
  136. }
  137. /***********************************************************
  138.  实现对输入二进制序列进行编码的功能
  139.  *********************************************************
  140. */
  141. void CDlgArith::OnCoding() 
  142. {
  143. // 输入二值序列长度
  144. int nInLength;
  145. // 输出码字长度
  146. int nOutLength;
  147. // 循环变量
  148. int i;
  149. // 中间变量
  150. double dTemp;
  151. // 编码区间的上限和下限  
  152. double dHigh=1.0;
  153. double dLow=0.0;
  154. // 编码区间的长度
  155. double dRange=1.0;
  156. // 累积概率
  157. double dAccuPro=1.0;
  158.     // 接收输入的数据
  159. UpdateData(TRUE);
  160. // 清除输出的编码码字
  161. m_ArithOutput = _T("");
  162. // 输出
  163. UpdateData(FALSE);
  164. // 令编码按钮无效
  165. m_decoding.EnableWindow(FALSE);
  166. // 输入的二值序列长度
  167. nInLength = m_ArithSerial.GetLength();
  168.  
  169. //  对二值序列进行编码
  170. for (i = 0; i < nInLength; i++ )
  171. {
  172. // 如果输入为1
  173. if(m_ArithSerial.Mid(i,1) == "1")
  174. {
  175. // 编码区间上下限的计算
  176. dHigh = dHigh;
  177. dLow  = dLow + dRange*fPro4Zero;
  178. // 编码区间长度
  179. dRange = dHigh - dLow;
  180. // 二值序列出现概率的计算
  181. dAccuPro = dAccuPro * fPro4One;
  182. }
  183. // 如果输入为0
  184. else if(m_ArithSerial.Mid(i,1) == "0")
  185. {
  186. // 编码区间上下限的计算
  187. dHigh = dLow + dRange*fPro4Zero;
  188. dLow  = dLow;
  189. // 编码区间长度
  190. dRange = dHigh - dLow;
  191. // 二值序列出现概率的计算
  192. dAccuPro = dAccuPro * fPro4Zero;
  193. }
  194. // 如果输入非二值序列
  195. else
  196. {
  197. // 重新输入
  198. MessageBox("请输入二值序列!", "系统提示" , 
  199. MB_ICONINFORMATION | MB_OK);
  200. return;
  201. }
  202. }
  203. // 计算输出码字的长度
  204. dTemp = floor( -log10(dAccuPro) / log10(2) ) + 1;
  205. nOutLength = (int)dTemp;
  206. dTemp = dLow;
  207. double d2Pow;
  208. // 将十进制的小数转化成二进制的小数表示
  209. for (i = 0; i < nOutLength; i++ )
  210. {
  211. // 二进制小数第i对应的十进制值
  212. d2Pow = pow(0.5,i + 1);
  213. // 判断当前位赋值0或者1
  214. if(dTemp >= d2Pow)
  215. {
  216. m_ArithOutput = m_ArithOutput + "1";
  217. dTemp = dTemp - d2Pow;
  218. }
  219. else 
  220. m_ArithOutput = m_ArithOutput + "0";
  221. }
  222. // 转化后是否有余数
  223. if(dTemp > 0)
  224. {
  225. // 二进制小数进行进位
  226. for(i = nOutLength-1; i >= 0; i--)
  227. {
  228. // 进位,1转化为0
  229. if(m_ArithOutput.Mid(i,1) == '1')
  230. {
  231. m_ArithOutput.Delete(i,1);
  232. m_ArithOutput.Insert(i,"0");
  233. }
  234. // 进位完成,最后的0位转化为1
  235. else
  236. {
  237. m_ArithOutput.Delete(i,1);
  238. m_ArithOutput.Insert(i,"1");
  239. break;
  240. }
  241. }
  242. }
  243.      
  244. // 编码完成,数据更新
  245. UpdateData(FALSE);
  246. // 允许进行解码
  247. m_decoding.EnableWindow(TRUE);
  248. // 解码前禁止编码
  249. m_coding.EnableWindow(FALSE);
  250. // 解码前禁止输入新的二进制序列
  251. m_ConArithSer.EnableWindow(FALSE);
  252. }