求哈夫曼解码的快速算法,小弟在次谢过了!

hqulyc 2004-03-22 10:33:02
如题
...全文
95 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
hqulyc 2004-03-23
  • 打赏
  • 举报
回复
????
hqulyc 2004-03-22
  • 打赏
  • 举报
回复
真的就没人会有哈夫曼解码的程序吧?
哎,顶下!
howtotell 2004-03-22
  • 打赏
  • 举报
回复
http://www.vckbase.com/code/downcode.asp?id=353
jpeg编码就要用到这个步骤。
hqulyc 2004-03-22
  • 打赏
  • 举报
回复
还是没人。。。

自己顶下!
topYellow 2004-03-22
  • 打赏
  • 举报
回复
数据结构书上有现成的啊
hqulyc 2004-03-22
  • 打赏
  • 举报
回复
自己顶下。。。。:(我的解码。。。。。?/每人有????
hqulyc 2004-03-22
  • 打赏
  • 举报
回复
恩,知道了,谢谢,可还是没有解码的程序???
lchlovely 2004-03-22
  • 打赏
  • 举报
回复
一個Byte是8bit,00000001=1,00000010=2,00000100=4;00001000=8
00010000=16;00100000=32;01000000=64;10000000=128;
unsigned char V = *((unsigned char *)lpDIBBits + lLineBytes * i + j);得到的是一個Byte的值,它最多有8位,

for (k = 0; k <min(8, strTemp.GetLength()); k++)
{
if (strTemp.Mid(k, 1) == "1")

T |= Mask[k];
}
這個循環就是對這8位逐個判斷其值.
lchlovely 2004-03-22
  • 打赏
  • 举报
回复
up
hqulyc 2004-03-22
  • 打赏
  • 举报
回复
BOOL CCoding::Huffman(HDIB hDIB, CString strPath)
{
// 循环变量
LONG i;
LONG j;
LONG k;

// 灰度计数
int nNs[256];

// 灰度概率分布
float fPs[256];

// 映射关系
int iMap[256];

// Huffman编码
CString m_strCode [256];

// 变量初始化
memset(nNs, 0, sizeof(nNs));

// 指向DIB的指针
LPBYTE lpDIB;

// 指向DIB象素指针
LPBYTE lpDIBBits;

// 锁定DIB
lpDIB = (LPBYTE) ::GlobalLock((HGLOBAL) hDIB);

// 找到DIB图像象素起始位置
lpDIBBits = m_clsDIB.FindDIBBits(lpDIB);

// 判断是否是24-bpp位图
if (m_clsDIB.DIBBitCount(lpDIB) != 24)
{
// 提示用户
MessageBox("请先将其转换为24位色位图,再进行处理!", "系统提示" , MB_ICONINFORMATION | MB_OK);

// 解除锁定
::GlobalUnlock((HGLOBAL) hDIB);

// 返回
return FALSE;
}

// 更改光标形状
BeginWaitCursor();

//////////////////////////////////////////////////////////
// 计算灰度概率分布

// DIB的宽度
LONG lWidth = m_clsDIB.DIBWidth(lpDIB);

// DIB的高度
LONG lHeight = m_clsDIB.DIBHeight(lpDIB);

// 计算图像每行的字节数
LONG lLineBytes = WIDTHBYTES(lWidth * 24);

// 对各像素进行灰度分布统计
for (i = 0; i < lHeight; i ++)
{
for (j = 0; j < lLineBytes; j ++)
{
// 对各像素进行灰度统计
unsigned char V = *((unsigned char *)lpDIBBits + lLineBytes * i + j);
nNs[V]++;
}
}

// 计算灰度分布密度
for(i = 0; i < 256; i++)
fPs[i] = nNs[i] / (lHeight * lLineBytes * 1.0f);

// 初始化
for (i = 0; i < 256; i ++)
iMap[i] = i;

//////////////////////////////////////////////////////////
// 用冒泡法对fPs[]进行排序

for (j = 0; j < 256 - 1; j ++)
{
for (i = 0; i < 256 - j - 1; i ++)
{
if (fPs[i] > fPs[i + 1])
{
// 互换
float fTemp = fPs[i];
fPs[i] = fPs[i + 1];
fPs[i + 1] = fTemp;

// 更新映射关系
for (k = 0; k < 256; k ++)
{
// 判断是否是fPs[i]的子节点
if (iMap[k] == i)
{
// 映射到节点i+1
iMap[k] = i + 1;
}
else if (iMap[k] == i + 1)
{
// 映射到节点i
iMap[k] = i;
}
}
}
}
}

//////////////////////////////////////////////////////////
// 计算哈夫曼编码表

for (i = 0; i < 256 - 1; i ++)
{
// 寻找第一个不为0的概率灰度级
if (fPs[i] > 0)
break;
}

// 开始编码
for (i = i; i < 256 - 1; i ++)
{
// 更新m_strCode
for (k = 0; k < 256; k ++)
{
// 判断是否是fPs[i]的子节点并编码字符串
if (iMap[k] == i)
m_strCode[k] = "1" + m_strCode[k];
else if (iMap[k] == i + 1)
m_strCode[k] = "0" + m_strCode[k];
}

// 概率最小的两个概率相加,结果保存到fPs[i + 1]
fPs[i + 1] += fPs[i];

// 改变映射关系
for (k = 0; k < 256; k ++)
{
// 判断是否是fPs[i]的子节点
if (iMap[k] == i)
{
// 映射到节点i+1
iMap[k] = i + 1;
}
}

// 重新排序
for (j = i + 1; j < 256 - 1; j ++)
{
if (fPs[j] > fPs[j + 1])
{
// 互换
float fTemp = fPs[j];
fPs[j] = fPs[j + 1];
fPs[j + 1] = fTemp;

// 更新映射关系
for (k = 0; k < 256; k ++)
{
// 判断是否是fPs[i]的子节点
if (iMap[k] == j)
{
// 映射到节点j+1
iMap[k] = j + 1;
}
else if (iMap[k] == j + 1)
{
// 映射到节点j
iMap[k] = j;
}
}
}
else
{
// 退出循环
break;
}
}
}


//////////////////////////////////////////////////////////
// 对DIB进行编码压缩

// 位掩码
unsigned char Mask[8] = {128, 64, 32, 16, 8, 4, 2, 1};
CString strTemp = "";

// 打开文件
CFile file;
file.Open(strPath, CFile::modeCreate | CFile::modeReadWrite);

// 对各像素进行编码
for(i = 0; i < lHeight; i ++)
{
for (j = 0; j < lLineBytes; j ++)
{
unsigned char V = *((unsigned char *)lpDIBBits + lLineBytes * i + j);
strTemp += m_strCode[V];
int len = strTemp.GetLength();
int loop = 0;

// 保存编码后的数据
do{
unsigned char T = 0;
for (k = 0; k <min(8, strTemp.GetLength()); k++)
{
if (strTemp.Mid(k, 1) == "1")
T |= Mask[k];
}

file.Write(&T, 1);
loop++;
len -= 8;
if (strTemp.GetLength() < 8)
break;
else
strTemp = strTemp.Right(strTemp.GetLength()- 8);
}while (len >= 8);
}
}

// 关闭文件
file.Close();

// 解除锁定
::GlobalUnlock((HGLOBAL) hDIB);

// 恢复光标
EndWaitCursor();

// 返回TRUE
return TRUE;
}

编码我有了!!!不太懂,为什么要为位掩码!!!!!!位掩码应该是对解码有什么意义吧!?大虾门帮帮忙了!!!

19,468

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧