⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dctview.cpp

📁 DCT离散余弦变换编码和解码
💻 CPP
字号:
// DCTView.cpp : CDCTView 类的实现
//

#include "stdafx.h"
#include "DCT.h"

#include "DCTDoc.h"
#include "DCTView.h"
#include ".\dctview.h"
#include ".\GetZNumDialog.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CDCTView

IMPLEMENT_DYNCREATE(CDCTView, CView)

BEGIN_MESSAGE_MAP(CDCTView, CView)
	// 标准打印命令
	ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
	ON_COMMAND(ID_OPENBMP, OnOpenbmp)
	ON_COMMAND(ID_DCT, OnDct)
	ON_COMMAND(ID_OPENDCT, OnOpendct)
	ON_COMMAND(ID_SETZNUM, OnSetznum)
	ON_COMMAND(ID_SAVEAS, OnSaveas)
END_MESSAGE_MAP()

// CDCTView 构造/析构

CDCTView::CDCTView()
{
	// TODO: 在此处添加构造代码

}

CDCTView::~CDCTView()
{
}

BOOL CDCTView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: 在此处通过修改 CREATESTRUCT cs 来修改窗口类或
	// 样式

	return CView::PreCreateWindow(cs);
}

// CDCTView 绘制

void CDCTView::OnDraw(CDC* pDC)
{
	CDCTDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;

	
	// TODO: 在此处为本机数据添加绘制代码
	if(!image.IsNull()) 
	{
		image.StretchBlt(*pDC,0,0,image.GetWidth(),image.GetHeight(),SRCCOPY);
	}
	else
	{
		if(pDoc->strBMPFileName.IsEmpty() == false)
		{
			image.Load(pDoc->strBMPFileName);
			
			Invalidate();
			UpdateWindow();
		}
	}
}


// CDCTView 打印

BOOL CDCTView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// 默认准备
	return DoPreparePrinting(pInfo);
}

void CDCTView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: 打印前添加额外的初始化
}

void CDCTView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: 打印后添加清除过程
}


// CDCTView 诊断

#ifdef _DEBUG
void CDCTView::AssertValid() const
{
	CView::AssertValid();
}

void CDCTView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CDCTDoc* CDCTView::GetDocument() const // 非调试版本是内联的
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CDCTDoc)));
	return (CDCTDoc*)m_pDocument;
}
#endif //_DEBUG


// CDCTView 消息处理程序

void CDCTView::OnOpenbmp()
{
	// TODO: 在此添加命令处理程序代码
	CFileDialog dlgOpenBMP(TRUE,_T("BMP"));
	if(dlgOpenBMP.DoModal() != IDOK)return;

	CString tempFileName;
	GetCurrentDirectory(60,tempFileName.GetBuffer(60));
	tempFileName.ReleaseBuffer();
	GetDocument()->strBMPFileName = tempFileName + "\\" + dlgOpenBMP.GetFileName();

	image.Destroy();
	image.Load(GetDocument()->strBMPFileName);
	
	Invalidate();
	UpdateWindow();
}

void CDCTView::OnDct()
{
	if(image.IsNull()) return;
	// TODO: 在此添加命令处理程序代码	
	
	CFileDialog dlgSaveFile(FALSE,"DAT");
	if(dlgSaveFile.DoModal() != IDOK) return;
	CString strFileName;
	GetCurrentDirectory(30,strFileName.GetBuffer(30));
	strFileName.ReleaseBuffer();
	strFileName += "\\"+dlgSaveFile.GetFileName();

	CFileException exception;
	CFile fileSave;
	if(!fileSave.Open(strFileName,CFile::modeCreate|CFile::modeWrite,&exception))
	{
		CString strErr;
		strErr.Format("err cause:%d",exception.m_cause);
		AfxMessageBox(strErr,0,0);
		return;
	}
	

	int BLOCKSIZE = 8;
	int Z_Amount = GetDocument()->Z_Num;
	int iColorNum = image.GetMaxColorTableEntries();
	int iDirection = image.GetPitch();
	int iWidth = image.GetWidth();
	iWidth = iWidth - iWidth % BLOCKSIZE;
	int iHeight = image.GetHeight();
	iHeight = iHeight - iHeight % BLOCKSIZE;
	int i,j,x,y;
	unsigned char * pbRGBElement = new BYTE[BLOCKSIZE*BLOCKSIZE];
	float * result = new float[Z_Amount];

	//unsigned char * pcBmpBits =(unsigned char *) image.GetBits();	
	RGBQUAD * prgbColors = new RGBQUAD[iColorNum];
	if(iColorNum != 0)image.GetColorTable(0,iColorNum,prgbColors);

	fileSave.Write((void *)&BLOCKSIZE,sizeof(int));
	fileSave.Write((void *)&Z_Amount,sizeof(int));
	fileSave.Write((void *)&iColorNum,sizeof(int));
	fileSave.Write((void *)&iWidth,sizeof(int));
	fileSave.Write((void *)&iHeight,sizeof(int));
	if(iColorNum != 0) fileSave.Write((void *)prgbColors,sizeof(RGBQUAD)*iColorNum);

	for(i = 0;i < iHeight; i+=BLOCKSIZE)
		for(j = 0;j < iWidth; j+=BLOCKSIZE)
		{
               for(x = 0;x < BLOCKSIZE;x++)
				   for(y=0;y <BLOCKSIZE;y++)
					   pbRGBElement[x*BLOCKSIZE + y] = GetRValue(image.GetPixel(j+y,i+x));
			   DCT(pbRGBElement,BLOCKSIZE,Z_Amount,result);
			   fileSave.Write((void *)result,sizeof(float)*Z_Amount);

			   for(x = 0;x < BLOCKSIZE;x++)
				   for(y=0;y <BLOCKSIZE;y++)
					   pbRGBElement[x*BLOCKSIZE + y] = GetGValue(image.GetPixel(j+y,i+x));
			   DCT(pbRGBElement,BLOCKSIZE,Z_Amount,result);
			   fileSave.Write((void *)result,sizeof(float)*Z_Amount);

			   for(x = 0;x < BLOCKSIZE;x++)
				   for(y=0;y <BLOCKSIZE;y++)
					   pbRGBElement[x*BLOCKSIZE + y] = GetBValue(image.GetPixel(j+y,i+x));
			   DCT(pbRGBElement,BLOCKSIZE,Z_Amount,result);
			   fileSave.Write((void *)result,sizeof(float)*Z_Amount);
		}

	fileSave.Close();

	delete[] pbRGBElement;
	delete[] result;
	delete[] prgbColors;

	CString msg;
	msg.Format("color entries num:%d,sizeof prgColors:%d",iColorNum,sizeof(RGBQUAD)*iColorNum);
	AfxMessageBox(msg,0,0);
}

void CDCTView::DCT(unsigned char * buffer_in,int BlockSize_in,int resultNum_in,float * result_out)
{

	int x,y,counter,u,v;
	float rTemp ;
	int COS_TABLE[8][8] = {
		{	32767,	32137,	30272,	27244,	23169,	18203,	12538,	6391},
		{	32767,	27244,	12538,	-6393,	-23171,	-32139,	-30274,	-18205},
		{	32767,	18203,	-12540,	-32139,	-23171,	6391,	30272,	27244},
		{	32767,	6391,	-30274,	-18205,	23169,	27244,	-12540,	-32139},
		{	32767,	-6393,	-30274,	18203,	23169,	-27246,	-12540,	32137},
		{	32767,	-18205,	-12540,	32137,	-23171,	-6393,	30272,	-27246},
		{	32767,	-27246,	12538,	6391,	-23171,	32137,	-30274,	18203},
		{	32767,	-32139,	30272,	-27246,	23169,	-18205,	12538,	-6393},
	};

	float * prTempMatrix = new float[BlockSize_in * BlockSize_in];
	
	for(u = 0; u<BlockSize_in;u++)
	{
		for(v=0; v<BlockSize_in;v++)
		{
			rTemp = 0.0f;
			for(x=0;x<BlockSize_in;x++)
				for(y=0;y<BlockSize_in;y++)
					rTemp += buffer_in[x*BlockSize_in + y] * COS_TABLE[y][v]/32767.0 *COS_TABLE[x][u]/32767.0;
			prTempMatrix[u*BlockSize_in + v] = rTemp * 0.25 * (u?1.0:23169/32767.0)*(v?1.0:23169/32767.0);

			//CString info;
			//info.Format("\t%f",prTempMatrix[u*BlockSize_in + v]);
			//traceFile.Write(info,info.GetLength());
		}
		
		//traceFile.Write("\n",1);
	}
	//traceFile.Write("========",8);
		
	//test whether the prTempMatrix value is between unsigned value

	//get specified value by Z-path
	for(x = 0, y=0, counter =0;counter < resultNum_in;counter ++)
	{
		result_out[counter] =  prTempMatrix[x * BlockSize_in + y];

		if((x+y)%2 == 0)
			if(x==0)
			{
				y + 1 >= BlockSize_in ? x++:y++;
			}
			else 
			{
                y + 1 >= BlockSize_in ? x++:(y++,x--);				
			}
		else
			if(y==0)
			{
				x + 1 >= BlockSize_in ? y++:x++;
			}
			else
			{
				x + 1 >= BlockSize_in ? y++:(y--,x++);
			}
		
	}
	delete[] prTempMatrix;
}

void CDCTView::OnOpendct()
{
	// TODO: 在此添加命令处理程序代码
	CString fileName;
	CFileDialog dlgOpenDCT(TRUE,_T("DAT"));
	if(dlgOpenDCT.DoModal() != IDOK) return;
	GetCurrentDirectory(30,fileName.GetBuffer(30));
	fileName.ReleaseBuffer();
	fileName += "\\" + dlgOpenDCT.GetFileName();

	CFileException exception;
	CFile fileOpen;
	if(!fileOpen.Open(fileName,CFile::modeRead,&exception))
	{
		CString msg;
		msg.Format("casue:%d",exception.m_cause);
		AfxMessageBox(msg,0,0);
		return;
	}

	//get info from my DCT file
	int BLOCKSIZE ;//= 8;
	int Z_Amount;// = 64;
	int iColorNum;// = image.GetMaxColorTableEntries();
	int iDirection;// = image.GetPitch();
	int iWidth;//= image.GetWidth();
	//iWidth = iWidth - iWidth % BLOCKSIZE;
	int iHeight;//=image.GetHeight();
	//iHeight = iHeight - iHeight % BLOCKSIZE;
	int i,j,x,y;

	fileOpen.Read((void *)&BLOCKSIZE,sizeof(int));
	fileOpen.Read((void *)&Z_Amount,sizeof(int));
	fileOpen.Read((void *)&iColorNum,sizeof(int));
	fileOpen.Read((void *)&iWidth,sizeof(int));
	fileOpen.Read((void *)&iHeight,sizeof(int));
	int bpp=0;
	if(iColorNum == 0)
		bpp = 24;
	else if(iColorNum == 256)
		bpp = 8;
	else if(iColorNum == 16)
		bpp= 4;
	else
	{
		CString msg;
		msg.Format("Sorry,I don't support color num:%d",iColorNum);
		AfxMessageBox(msg,0,0);
		fileOpen.Close();
		return;
	}

	image.Destroy();
	image.Create(iWidth,iHeight,bpp);
	
	unsigned char * pbR = new BYTE[BLOCKSIZE*BLOCKSIZE];
	unsigned char * pbG = new BYTE[BLOCKSIZE*BLOCKSIZE];
	unsigned char * pbB = new BYTE[BLOCKSIZE*BLOCKSIZE];
	float * result = new float[Z_Amount];

	//unsigned char * pcBmpBits =(unsigned char *) image.GetBits();	
	RGBQUAD * prgbColors = new RGBQUAD[iColorNum];
	if(iColorNum != 0)
	{
		fileOpen.Read((void *)prgbColors,sizeof(RGBQUAD)*iColorNum);
		image.SetColorTable(0,iColorNum,prgbColors);		
	}	

	for(i = 0;i < iHeight; i+=BLOCKSIZE)
		for(j = 0;j < iWidth; j+=BLOCKSIZE)
		{
			fileOpen.Read((void *)result,sizeof(float)*Z_Amount);
			IDCT(result,BLOCKSIZE,Z_Amount,pbR);

			fileOpen.Read((void *)result,sizeof(float)*Z_Amount);
			IDCT(result,BLOCKSIZE,Z_Amount,pbG);

			fileOpen.Read((void *)result,sizeof(float)*Z_Amount);
			IDCT(result,BLOCKSIZE,Z_Amount,pbB);

			for(x = 0;x < BLOCKSIZE;x++)
				for(y=0;y <BLOCKSIZE;y++)
					image.SetPixel(j+y,i+x,RGB(pbR[x*BLOCKSIZE+y],pbG[x*BLOCKSIZE+y],pbB[x*BLOCKSIZE+y]));
		}
	
	fileOpen.Close();

	delete[] pbR;
	delete[] pbG;
	delete[] pbB;
	delete[] result;
	delete[] prgbColors;
	
	
	Invalidate();
	UpdateWindow();
}

void CDCTView::IDCT(float * result_in,int BlockSize_in,int resultNum_in,unsigned char * buffer_out)
{
	int x,y,counter,u,v,TOTAL=BlockSize_in * BlockSize_in;
	float rTemp ;
	int COS_TABLE[8][8] = {
		{	32767,	32137,	30272,	27244,	23169,	18203,	12538,	6391},
		{	32767,	27244,	12538,	-6393,	-23171,	-32139,	-30274,	-18205},
		{	32767,	18203,	-12540,	-32139,	-23171,	6391,	30272,	27244},
		{	32767,	6391,	-30274,	-18205,	23169,	27244,	-12540,	-32139},
		{	32767,	-6393,	-30274,	18203,	23169,	-27246,	-12540,	32137},
		{	32767,	-18205,	-12540,	32137,	-23171,	-6393,	30272,	-27246},
		{	32767,	-27246,	12538,	6391,	-23171,	32137,	-30274,	18203},
		{	32767,	-32139,	30272,	-27246,	23169,	-18205,	12538,	-6393},
	};

	float * prTempMatrix = new float[TOTAL];

	//build up a original size DCT value matrix for Innverse DCT later.
	for(x = 0, y=0, counter =0;counter < TOTAL;counter ++)
	{
		prTempMatrix[x * BlockSize_in + y] = (counter < resultNum_in?result_in[counter]:0);

		if((x+y)%2 == 0)
			if(x==0)
			{
				y + 1 >= BlockSize_in ? x++:y++;
			}
			else 
			{
                y + 1 >= BlockSize_in ? x++:(y++,x--);				
			}
		else
			if(y==0)
			{
				x + 1 >= BlockSize_in ? y++:x++;
			}
			else
			{
				x + 1 >= BlockSize_in ? y++:(y--,x++);
			}		
		
	}//end for counter

	//compute original pixal value
	for(x=0; x<BlockSize_in;x++)
		for(y=0; y<BlockSize_in;y++)
		{
			rTemp = 0.0f;
			for(u=0;u<BlockSize_in;u++)
				for(v=0;v<BlockSize_in;v++)
					rTemp += (u?1.0:23169/32767.0) * (v?1.0:23169/32767.0) * prTempMatrix [u*BlockSize_in + v] * COS_TABLE[u][x]/32767.0 * COS_TABLE[v][y]/32767.0;
			buffer_out[x*BlockSize_in + y] = rTemp * 0.25 ;
		}

    delete[] prTempMatrix;
}

void CDCTView::OnSetznum()
{
	// TODO: 在此添加命令处理程序代码
	CGetZNumDialog dlgGetZNum;
	if(dlgGetZNum.DoModal() == IDOK)
	{
		int value = atoi(dlgGetZNum.strZValue);
		if(value == 0)
			AfxMessageBox(_T("非法Z范围") ,0,0);
		else 
			GetDocument()->Z_Num = value;
	}
}

void CDCTView::OnSaveas()
{
	// TODO: 在此添加命令处理程序代码
	if(image.IsNull())
	{
		AfxMessageBox("没有有效的BMP文件来保存",0,0);
		return;
	}
	CString fileName;
	CFileDialog dlgOpenDCT(TRUE,_T("BMP"));
	if(dlgOpenDCT.DoModal() != IDOK) return;
	GetCurrentDirectory(30,fileName.GetBuffer(30));
	fileName.ReleaseBuffer();
	fileName += "\\" + dlgOpenDCT.GetFileName();

	image.Save(fileName);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -