📄 decompressdoc.cpp
字号:
// DecompressDoc.cpp : implementation of the CDecompressDoc class
//
#include "stdafx.h"
#include "Decompress.h"
#include "DecompressDoc.h"
#include "ScanNumDlg.h"
#include <math.h>
#include <time.h>
#include <Afx.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CDecompressDoc
IMPLEMENT_DYNCREATE(CDecompressDoc, CDocument)
BEGIN_MESSAGE_MAP(CDecompressDoc, CDocument)
//{{AFX_MSG_MAP(CDecompressDoc)
ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
ON_COMMAND(ID_FileClose, OnFileClose)
ON_COMMAND(ID_HaarOne, OnHaarOne)
ON_COMMAND(ID_HaarTwo, OnHaarTwo)
ON_COMMAND(ID_HaarThree, OnHaarThree)
ON_COMMAND(ID_D97One, OnD97One)
ON_COMMAND(ID_D97Two, OnD97Two)
ON_COMMAND(ID_D97Three, OnD97Three)
ON_COMMAND(ID_FILE_SAVE_AS, OnFileSaveAs)
ON_COMMAND(ID_EZW_Encode, OnEZWEncode)
ON_COMMAND(ID_EZW_Decode, OnEZWDecode)
ON_COMMAND(ID_HaarFour, OnHaarFour)
ON_COMMAND(ID_D97Four, OnD97Four)
ON_COMMAND(ID_FourFind, OnFourFind)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDecompressDoc construction/destruction
CDecompressDoc::CDecompressDoc()
{
// TODO: add one-time construction code here
scale=0;
code.SetSize(500,200);
codeId=0;
}
CDecompressDoc::~CDecompressDoc()
{
if(flag==1)
{
for(int i=0;i<pbi->bmiHeader.biHeight;i++)
delete []Coefficient[i];
delete []Coefficient;
HeapFree(GetProcessHeap(), 0, pbi);
HeapFree(GetProcessHeap(), 0, lpBuf);
HeapFree(GetProcessHeap(), 0, lpshowbuf);
}
code.RemoveAll();
}
BOOL CDecompressDoc::OnNewDocument()
{
if (!CDocument::OnNewDocument())
return FALSE;
// TODO: add reinitialization code here
// (SDI documents will reuse this document)
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CDecompressDoc serialization
void CDecompressDoc::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{
// TODO: add storing code here
}
else
{
// TODO: add loading code here
}
}
/////////////////////////////////////////////////////////////////////////////
// CDecompressDoc diagnostics
#ifdef _DEBUG
void CDecompressDoc::AssertValid() const
{
CDocument::AssertValid();
}
void CDecompressDoc::Dump(CDumpContext& dc) const
{
CDocument::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CDecompressDoc commands
void CDecompressDoc::OnFileOpen()
{
// TODO: Add your command handler code here
LPCTSTR lpszFilter="BMP Files(*.bmp)|*.bmp|任何文件|*.*||";
CFileDialog dlg(TRUE, lpszFilter, NULL, OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, lpszFilter, NULL);
CString filename;
CFile file;
//BITMAPFILEHEADER bf;
//打开文件对话框
if(dlg.DoModal()==IDOK)
{
filename=dlg.GetPathName();
if(file.Open(filename, CFile::modeRead|CFile::shareDenyNone, NULL)==0)
{
//读取文件失败
AfxMessageBox("无法打开文件!", MB_OK, 0);
return;
}
//读取文件头
file.Read(&bf,sizeof(bf));
//判断是否是BMP文件
if(bf.bfType!=0x4d42) //'BM'
{
AfxMessageBox("非BMP文件!", MB_OK, 0);
return;
}
//判断文件是否损坏
if(file.GetLength()!=bf.bfSize)
{
AfxMessageBox("文件已损坏,请检查!", MB_OK, 0);
return;
}
//读文件信息头
file.Read(&bi, sizeof(bi));
//计算调色板数目
numQuad=0;
if(bi.biBitCount<24)
{
numQuad=1<<bi.biBitCount;
}
//为图像信息pbi申请空间
pbi=(BITMAPINFO*)HeapAlloc(GetProcessHeap(), 0, sizeof(BITMAPINFOHEADER)+numQuad*sizeof(RGBQUAD));
memcpy(pbi, &bi, sizeof(bi));
quad=(RGBQUAD*)((BYTE*)pbi+sizeof(BITMAPINFOHEADER));
int linewidth=(pbi->bmiHeader.biWidth*pbi->bmiHeader.biBitCount+31)/32*4;
Coefficient=new int*[pbi->bmiHeader.biHeight];
for(int i=0;i<pbi->bmiHeader.biHeight;i++)
Coefficient[i]=new int[linewidth];
//读取调色板
if(numQuad!=0)
{
file.Read(quad, sizeof(RGBQUAD)*numQuad);
}
//检测调色板是否为整数型
//AfxMessageBox("第一个值是:"+quad->rgbBlue,MB_OK,0);
//为图像数据申请空间
bi.biSizeImage=bf.bfSize-bf.bfOffBits;
lpBuf=(BYTE*)HeapAlloc(GetProcessHeap(), 0, bi.biSizeImage);
//读取图像数据
file.Read(lpBuf, bi.biSizeImage);
//图像读取完毕,关闭文件,设置标志
file.Close();
flag=1;
lpshowbuf=NULL;
PrepareShowdata();
//将BMP图像显示出来
UpdateAllViews(NULL, 0, NULL);
}
}
BOOL CDecompressDoc::PrepareShowdata()
{
BYTE** image;
BYTE** originimage;
int i,j;
int linewidth;
//char *ch;
// int size;
if(lpshowbuf!=NULL)
HeapFree(GetProcessHeap(), 0, lpshowbuf);
//申请内存
linewidth=(pbi->bmiHeader.biWidth*pbi->bmiHeader.biBitCount+31)/32*4;
pbi->bmiHeader.biSizeImage=linewidth*pbi->bmiHeader.biHeight;
lpshowbuf=(BYTE*)HeapAlloc(GetProcessHeap(), 0, sizeof(BYTE)*pbi->bmiHeader.biSizeImage);
//生成对lpshowbuf的二维数组索引
image=new BYTE*[pbi->bmiHeader.biHeight];
for(i=0;i<pbi->bmiHeader.biHeight;i++)
image[i]=lpshowbuf+i*linewidth;
originimage=new BYTE*[pbi->bmiHeader.biHeight];
for(i=0;i<pbi->bmiHeader.biHeight;i++)
originimage[i]=lpBuf+i*linewidth;
//赋值
if(bi.biBitCount<24) //含有调色板的情况
{
//BYTE temp;
for(i=0;i<pbi->bmiHeader.biHeight;i++)
for(j=0;j<linewidth;j++)
{
image[i][j]=originimage[i][j];
//image[i][j*3]=quad[temp].rgbBlue;
//image[i][j*3+1]=quad[temp].rgbGreen;
//image[i][j*3+2]=quad[temp].rgbRed;
}
//for(DWORD i=0;i<(3*pbi->bmiHeader.biSizeImage);i++)
//ch[i]=lpshowbuf[i];
}
else if(pbi->bmiHeader.biBitCount==24) //24位真彩色
{
for(i=0;i<pbi->bmiHeader.biHeight;i++)
for(j=0;j<pbi->bmiHeader.biWidth;j++)
{
image[i][j*3]=originimage[i][j*3];
image[i][j*3+1]=originimage[i][j*3+1];
image[i][j*3+2]=originimage[i][j*3+2];
}
//for(DWORD i=0;i<pbi->bmiHeader.biSizeImage;i++)
//str[i].Format("%d",lpshowbuf[i]);
//ch[i]=lpshowbuf[i];
}
//str=ch;
//AfxMessageBox(str,MB_OK,0);
//CFile file;
//if(file.Open("d:\\openfile.txt",CFile::modeRead|CFile::shareDenyNone, NULL)==0)
// file.Write(lpshowbuf,pbi->bmiHeader.biSizeImage);
//ofstream ofile("d:\\openfile1.txt",ios::in,filebuf::openprot);
//for(long ii=0;ii<pbi->bmiHeader.biSizeImage;ii++)
//{
// int in=(int)lpshowbuf[ii];
// if(ii%3==0)
// ofile<<' ';
// ofile<<in;
//}
// ofile.close();
delete []image;
return TRUE;
}
void CDecompressDoc::OnFileClose()
{
// TODO: Add your command handler code here
if(flag==1)
lpshowbuf=NULL;
UpdateAllViews(NULL, 0, NULL);
}
void CDecompressDoc::OnHaarOne()
{
// TODO: Add your command handler code here
int linewidth;
int max, min; //记录变换后像素的最大最小值
int** image; //用于变换的整型图象数据
//int temp; //临时存放映射后的值,再转化为BYTE型
linewidth=(pbi->bmiHeader.biWidth*pbi->bmiHeader.biBitCount+31)/32*4;
JiFlag=0; //Haar小波
//生成对lpBuf的二维数组索引
image=new int*[pbi->bmiHeader.biHeight];
for(int i=0;i<pbi->bmiHeader.biHeight;i++)
{
image[i]=new int[linewidth];
// image[i]=(int*)(lpBuf+i*linewidth);
}
for(int ii=pbi->bmiHeader.biHeight-1; ii>=0; ii--)
{
for(int jj=0; jj<linewidth; jj++)
image[ii][jj]=*(lpBuf+(pbi->bmiHeader.biHeight-1-ii)*linewidth+jj);
}
max=min=image[0][0];
HaarTrans(pbi->bmiHeader.biHeight,linewidth,image,&max,&min);
GetCoefficient(image,pbi->bmiHeader.biHeight,linewidth);
One_ToLpshowbuf(image, &max, &min);
scale=1;
//释放内存
for(int z=0;z<pbi->bmiHeader.biHeight;z++)
{
delete [] image[z];
}
delete [] image;
UpdateAllViews(NULL, 0, NULL);
}
void CDecompressDoc::HaarTrans(int height, int width, int **data, int *max, int *min)
{
//行变换
int i,j;
int** s=new int*[width>>1];
int** d=new int*[width>>1];
for(i=0;i<(width>>1);i++)
{
s[i]=new int[height];
d[i]=new int[height];
}
LineSplit(data,s,d,height,width);//实现分裂
HaarForecast(s,d,height,width);
for(i=0;i<height;i++) //
{
for(j=0;j<width>>1;j++)
{
data[i][2*j]=s[j][i];
data[i][2*j+1]=d[j][i];
}
}
for(i=0;i<(width>>1);i++)
{
delete [] s[i];
delete [] d[i];
}
delete [] s;
delete [] d;
//列变换
s=new int*[height>>1];
d=new int*[height>>1];
for(i=0;i<(height>>1);i++)
{
s[i]=new int[width];
d[i]=new int[width];
}
RowSplit(data,s,d,height,width);
HaarForecast(s,d,width,height);
for(i=0;i<height>>1;i++)
{
for(j=0;j<width;j++)
{
data[2*i][j]=s[i][j];
data[2*i+1][j]=d[i][j];
if(data[2*i][j]>*max)
*max=data[2*i][j];
else if(data[2*i][j]<*min)
*min=data[2*i][j];
if(data[2*i+1][j]>*max)
*max=data[2*i+1][j];
else if(data[2*i+1][j]<*min)
*min=data[2*i+1][j];
}
}
for(i=0;i<(height>>1);i++)
{
delete [] s[i];
delete [] d[i];
}
delete [] s;
delete [] d;
}
//行变换中的分裂
void CDecompressDoc::LineSplit(int **data, int **s, int **d, int height, int width)
{
for(int i=0;i<height;i++)
{
for(int j=0;j<width>>1;j++)
{
s[j][i]=data[i][2*j];
d[j][i]=data[i][2*j+1];
}
}
}
//列变换中的分裂
void CDecompressDoc::RowSplit(int** data, int** s, int** d, int height, int width)
{
for(int i=0;i<height>>1;i++)
{
for(int j=0;j<width;j++)
{
s[i][j]=data[2*i][j];
d[i][j]=data[2*i+1][j];
}
}
}
//Haar变换中的预测和提升
void CDecompressDoc::HaarForecast(int **s, int **d, int height, int width)
{
int i,j;
for(i=0;i<(width>>1);i++)
{
for(j=0;j<height;j++)
{
d[i][j]=d[i][j]-s[i][j];
}
}
for(i=0;i<(width>>1);i++)
{
for(j=0;j<height;j++)
{
s[i][j]=s[i][j]+d[i][j]/2;
}
}
}
void CDecompressDoc::One_ToLpshowbuf(int **OneImage, int *max, int *min)
{
int temp;
int linewidth=(pbi->bmiHeader.biWidth*pbi->bmiHeader.biBitCount+31)/32*4;
//把所有变换后的像素值映射到0-255,且把变换后的值正确的存入lpshowbuf中
for(int mm=0;mm<pbi->bmiHeader.biHeight;mm++)
{
for(int nn=0;nn<linewidth;nn++)
OneImage[mm][nn]=(OneImage[mm][nn]-*min)*255/(*max-*min);
}
for(int m=0; m<pbi->bmiHeader.biHeight>>1; m++)
{
for(int n=0; n<linewidth>>1; n++)
{
temp=OneImage[2*m][2*n];
//lpshowbuf[m*linewidth+n]=(BYTE)image[2*m][n];
lpshowbuf[(pbi->bmiHeader.biHeight-1-m)*linewidth+n]=(BYTE)temp;
temp=OneImage[2*m][2*n+1];
lpshowbuf[((pbi->bmiHeader.biHeight>>1)-1-m)*linewidth+n]=(BYTE)temp;
temp=OneImage[2*m+1][2*n];
lpshowbuf[(pbi->bmiHeader.biHeight-1-m)*linewidth+(linewidth>>1)-1+n]=(BYTE)temp;
temp=OneImage[2*m+1][2*n+1];
lpshowbuf[((pbi->bmiHeader.biHeight>>1)-1-m)*linewidth+(linewidth>>1)-1+n]=(BYTE)temp;
}
}
}
void CDecompressDoc::OnHaarTwo()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -