用于实现JPEG编解码的CJpeg类的定义Word文档格式.docx
《用于实现JPEG编解码的CJpeg类的定义Word文档格式.docx》由会员分享,可在线阅读,更多相关《用于实现JPEG编解码的CJpeg类的定义Word文档格式.docx(19页珍藏版)》请在冰豆网上搜索。
![用于实现JPEG编解码的CJpeg类的定义Word文档格式.docx](https://file1.bdocx.com/fileroot1/2022-11/25/dce7baa6-0ca0-4a4a-bdc1-39f09833af70/dce7baa6-0ca0-4a4a-bdc1-39f09833af701.gif)
FLOAT*m_fFreq;
//哈夫曼编码表
CString*m_strCode;
//Overrides
//ClassWizardgeneratedvirtualfunctionoverrides
//{{AFX_VIRTUAL(CDlgHuffman)
protected:
virtualvoidDoDataExchange(CDataExchange*pDX);
//DDX/DDVsupport
//}}AFX_VIRTUAL
//Implementation
protected:
//Generatedmessagemapfunctions
//{{AFX_MSG(CDlgHuffman)
virtualBOOLOnInitDialog();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
3)重载视图类的OnInitialUpdate()函数,用于获取DIB文件的信息来设置滚动显示范围。
voidCHuffmanExpView:
:
OnInitialUpdate()
CScrollView:
OnInitialUpdate();
CHuffmanExpDoc*pDoc=GetDocument();
CSizesizeTotal(pDoc->
m_pDib->
GetWidth(),pDoc->
GetHeight());
SetScrollSizes(MM_TEXT,sizeTotal);
CMainFrame*pAppFrame=(CMainFrame*)AfxGetApp()->
m_pMainWnd;
ASSERT_KINDOF(CMainFrame,pAppFrame);
CRectrc;
pAppFrame->
GetClientRect(&
rc);
if(rc.Width()>
=sizeTotal.cx&
&
rc.Height()>
=sizeTotal.cy&
(sizeTotal.cx>
0||sizeTotal.cy>
0))
ResizeParentToFit(FALSE);
}
4)重载视图类的OnDraw(CDC*pDC)函数实现图像显示。
OnDraw(CDC*pDC)
ASSERT_VALID(pDoc);
//TODO:
adddrawcodefornativedatahere
if(!
pDoc->
IsEmpty())
pDoc->
Display(pDC,0,0);
其中CDib类的各成员函数为:
classCDib:
publicCObject
{
DECLARE_SERIAL(CDib)
//Publicmemberfunction
//constructor
CDib();
//create
BOOLCreate(DWORDdwWidth,DWORDdwHeight);
BOOLCreate(DWORDdwWidth,DWORDdwHeight,WORDwBitCount);
BOOLCreate(LPBYTElpDIB);
BOOLCreate(LPBYTElpDIB,//DIBpointer
WORDwBitCount);
//bits/pixel
BOOLCreate(HBITMAPhBitmap);
//DIBSection
BOOLCreate(HBITMAPhBitmap,//DIBSection
BOOLCreate(HBITMAPhBitmap,//Bitmaphandle
HPALETTEhPalette);
//Palettehandle
HPALETTEhPalette,//Palettehandle
BOOLCreate(CRectrcScreen);
BOOLCreate(HWNDhWnd,WORDfPrintArea);
BOOLCreate(HWNDhWnd,CRectrcClientArea);
//load/save
BOOLLoad(UINTuIDS,LPCTSTRlpszDibType);
BOOLLoad(LPCTSTRlpszDibRes,LPCTSTRlpszDibType);
BOOLLoad(LPCTSTRlpszDibFile);
BOOLSave(LPCTSTRlpszDibFile);
BOOLRead(CFile*pFile);
BOOLWrite(CFile*pFile);
//clone
CDib*Clone();
//deconstructor
virtual~CDib();
//destroy
voidDestroy();
//overlayingSerialize
virtualvoidSerialize(CArchive&
ar);
//display
BOOLDisplay(CDC*pDC,intxDest,intyDest,intnWidthDest,intnHeightDest,intxSrc,intySrc,DWORDdwRop=SRCCOPY);
BOOLDisplay(CDC*pDC,intxDest,intyDest,intnWidthDest,intnHeightDest,intxSrc,intySrc,intnWidthSrc,intnHeightSrc,DWORDdwRop=SRCCOPY);
BOOLDisplay(CDC*pDC,intx,inty,DWORDdwRop=SRCCOPY);
BOOLDisplay(CDC*pDC,CRectrcDest,CRectrcSrc,DWORDdwRop=SRCCOPY);
BOOLDisplayPalette(CDC*pDC,CRectrc);
//DCformodifyDIB
CDC*BeginPaint(CDC*pDC);
voidEndPaint();
//DDBandpalette
BOOLBuildBitmap();
BOOLBuildPalette();
//attributes
BOOLIsEmpty();
DWORDGetCompression();
WORDGetBitCount();
LONGGetWidth();
LONGGetHeight();
LONGGetWidthBytes();
WORDGetColorNumber();
WORDGetPaletteSize();
CBitmap*GetBitmap();
CPalette*GetPalette();
HANDLEGetHandle();
LPBYTEGetBitsPtr();
COLORREFGetPixel(LONGx,LONGy);
LONGGetPixelOffset(LONGx,LONGy);
//privatememberfunction
private:
BOOLUpdateInternal();
//publicmemberdata
HDIBm_hDib;
HBITMAPm_hBitmap;
//handleofDIBSection
CPalette*m_pPalette;
CBitmap*m_pBitmap;
//privatememberdata
//fordrawinginDIB
CDC*m_pMemDC;
CBitmap*m_pBitmapTmp;
CPalette*m_pPaletteTmp;
其函数定义参考例程中的Dib.cpp文件。
2、添加[图像编码]菜单及子菜单[哈夫曼编码],使用该菜单打开用于显示哈夫曼编码信息的对话框,执行相应哈夫曼编码处理和显示。
(1)创建菜单资源。
[哈夫曼编码]菜单资源号为:
ID_HUFFMAN
(2)定义菜单命令响应函数
OnHuffman()
Addyourcommandhandlercodehere
//查看哈夫曼编码表
//获取文档
//指向源图像象素的指针
unsignedchar*lpSrc;
//指向DIB的指针
LPBYTElpDIB;
//指向DIB象素指针
LPBYTElpDIBBits;
//DIB的高度
LONGlHeight;
//DIB的宽度
LONGlWidth;
//图像每行的字节数
LONGlLineBytes;
//图像象素总数
LONGlCountSum;
//循环变量
LONGi;
LONGj;
//保存各个灰度值频率的数组指针
FLOAT*fFreq;
//获取当前DIB颜色数目
intiColorNum;
//锁定DIB
lpDIB=(LPBYTE):
GlobalLock((HGLOBAL)pDoc->
m_hDib);
//找到DIB图像象素起始位置
lpDIBBits=:
FindDIBBits(lpDIB);
iColorNum=:
DIBNumColors(lpDIB);
//判断是否是8-bpp位图(这里为了方便,只处理8-bpp位图,其它的可以类推)
if(iColorNum!
=256)
{
//提示用户
MessageBox("
目前只支持256色位图哈夫曼编码!
"
"
系统提示"
MB_ICONINFORMATION|MB_OK);
//解除锁定
:
GlobalUnlock((HGLOBAL)pDoc->
//返回
return;
}
//更改光标形状
BeginWaitCursor();
//分配内存
fFreq=newFLOAT[iColorNum];
//计算DIB宽度
lWidth=:
DIBWidth(lpDIB);
//计算DIB高度
lHeight=:
DIBHeight(lpDIB);
//计算图像每行的字节数
lLineBytes=WIDTHBYTES(lWidth*8);
//重置计数为0
for(i=0;
i<
iColorNum;
i++)
//清零
fFreq[i]=0.0;
//计算各个灰度值的计数(对于非256色位图,此处给数组fFreq赋值方法将不同)
lHeight;
for(j=0;
j<
lWidth;
j++)
{
//指向图像指针
lpSrc=(unsignedchar*)lpDIBBits+lLineBytes*i+j;
//计数加1
fFreq[*(lpSrc)]+=1;
}
//计算图像象素总数
lCountSum=lHeight*lWidth;
//计算各个灰度值出现的概率
//计算概率
fFreq[i]/=(FLOAT)lCountSum;
//计算各个灰度级出现的频率结束
/*****************************************************************************/
//创建对话框
CDlgHuffmandlgPara;
//初始化变量值
dlgPara.m_fFreq=fFreq;
dlgPara.m_iColorNum=iColorNum;
//显示对话框
dlgPara.DoModal();
//解除锁定
//恢复光标
EndWaitCursor();
(3)
BOOLCDlgHuffman:
OnInitDialog()
//CDialog:
OnInitDialog();
Addextrainitializationhere
//字符串变量
CStringstr;
LONGk;
//中间变量
FLOATfT;
//ListCtrl的ITEM
LV_ITEMlvitem;
//中间变量,保存ListCtrl中添加的ITEM编号
intiActualItem;
//调用默认得OnInitDialog()函数
CDialog:
//初始化变量
m_dEntropy=0.0;
m_dAvgCodeLen=0.0;
//计算图像熵
m_iColorNum;
//判断概率是否大于0
if(m_fFreq[i]>
0)
//计算图像熵
m_dEntropy-=m_fFreq[i]*log(m_fFreq[i])/log(2.0);
//保存计算中间结果的数组
FLOAT*fTemp;
//保存映射关系的数组
int*iMap;
fTemp=newFLOAT[m_iColorNum];
iMap=newint[m_iColorNum];
m_strCode=newCString[m_iColorNum];
//初始化fTemp为m_fFreq
//赋值
fTemp[i]=m_fFreq[i];
iMap[i]=i;
//用冒泡法对进行灰度值出现的概率排序,结果保存在数组fTemp中
for(j=0;
m_iColorNum-1;
for(i=0;
m_iColorNum-j-1;
if(fTemp[i]>
fTemp[i+1])
{
//互换
fT=fTemp[i];
fTemp[i]=fTemp[i+1];
fTemp[i+1]=fT;
//更新映射关系
for(k=0;
k<
k++)
{
//判断是否是fTemp[i]的子节点
if(iMap[k]==i)
{
//改变映射到节点i+1
iMap[k]=i+1;
}
elseif(iMap[k]==i+1)
//改变映射到节点i
iMap[k]=i;
}
}
//////////////////////////////////////////////////////////
//计算哈夫曼编码表
//找到概率大于0处才开始编码
if(fTemp[i]>
break;
//开始编码
for(;
//更新m_strCode
for(k=0;
//判断是否是fTemp[i]的子节点
if(iMap[k]==i)
//改变编码字符串
m_strCode[k]="
1"
+m_strCode[k];
elseif(iMap[k]==i+1)
0"
//概率最小的两个概率相加,保存在fTemp[i+1]中
fTemp[i+1]+=fTemp[i];
//改变映射关系
//改变映射到节点i+1
iMap[k]=i+1;
//重新排序
for(j=i+1;
if(fTemp[j]>
fTemp[j+1])
fT=fTemp[j];
fTemp[j]=fTemp[j+1];
fTemp[j+1]=fT;
if(iMap[k]==j)
//改变映射到节点j+1
iMap[k]=j+1;
elseif(iMap[k]==j+1)
//改变映射到节点j
iMap[k]=j;
else
//退出循环
break;
//计算平均码字长度
//累加
m_dAvgCodeLen+=m_fFreq[i]*m_strCode[i].GetLength();
//计算编码效率
m_dEfficiency=m_dEntropy/m_dAvgCodeLen;
//保存变动
UpdateData(FALSE);
//输出计算结果
//设置List控件样式
m_lstTable.ModifyStyle(LVS_TYPEMASK,LVS_REPORT);
//给List控件添加Header
m_lstTable.InsertColumn(0,"
灰