MFC의 첫 도전.. ㅜㅜ
원본은 Lena.raw 512x512의 일반적인 Raw화일..
DCT하는데 8x8로 나눠서 하므로 원본 사이즈가 8의 배수여야함...
VS2005에서 MFC로 작성...
따라서 AfxMessageBox(L"iQuantization 변환 성공!", MB_OK, 0); 같이 기존 VS 6.0 에서의 MFC 문법과는 살짝 달라짐;;;
그냥 MainFrm.cpp만 올림... 사용법은 알아서;;;
닫기
Code Type : CPP
// MainFrm.cpp : CMainFrame 클래스의 구현
//
#include "stdafx.h"
#include "2002711158_Ohyung_12th_report.h"
#include "MainFrm.h"
#include < stdio.h>
#include < stdlib.h>
#include < math.h>
#include < time.h>
//#define SIZE 128
#define SIZE 512
#define MSIZE SIZE / 2
#define PI 3.141592
#define PI2 6.283184
time_t s_time, e_time;
CString message;
int QuantMatrix[8][8]={16, 11, 10, 16, 24, 40, 51, 61,
12, 12, 14, 19, 26, 58, 60, 55,
14, 13, 16, 24, 40, 57, 69, 56,
14, 17, 22, 29, 51, 87, 80, 62,
18, 22, 37, 56, 68, 109, 103, 77,
24, 35, 55, 64, 81, 104, 113, 92,
49, 64, 78, 87, 103, 121, 120, 101,
72, 92, 95, 98, 112, 100, 103, 99};
static unsigned char lena_origin[SIZE][SIZE];
static unsigned char lena_dct[SIZE][SIZE];
static unsigned char lena_idct[SIZE][SIZE];
static unsigned char lena_quant[SIZE][SIZE];
static unsigned char lena_iquant[SIZE][SIZE];
static double lena_temp[SIZE][SIZE];
int viewWhat = 1;
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CMainFrame
IMPLEMENT_DYNAMIC(CMainFrame, CFrameWnd)
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
ON_WM_CREATE()
ON_WM_SETFOCUS()
ON_COMMAND(ID_APP_OPEN, &CMainFrame::OnAppOpen)
ON_COMMAND(ID_APP_VIEW, &CMainFrame::OnAppView)
ON_COMMAND(ID_APP_DCT, &CMainFrame::OnAppDct)
ON_COMMAND(ID_APP_iDCT, &CMainFrame::OnAppidct)
ON_COMMAND(ID_APP_Quant, &CMainFrame::OnAppQuant)
ON_COMMAND(ID_APP_iQuant, &CMainFrame::OnAppiquant)
END_MESSAGE_MAP()
static UINT indicators[] =
{
ID_SEPARATOR, // 상태 줄 표시기
ID_INDICATOR_CAPS,
ID_INDICATOR_NUM,
ID_INDICATOR_SCRL,
};
// CMainFrame 생성/소멸
CMainFrame::CMainFrame()
{
// TODO: 여기에 멤버 초기화 코드를 추가합니다.
}
CMainFrame::~CMainFrame()
{
}
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
// 프레임의 클라이언트 영역을 차지하는 뷰를 만듭니다.
if (!m_wndView.Create(NULL, NULL, AFX_WS_DEFAULT_VIEW,
CRect(0, 0, 0, 0), this, AFX_IDW_PANE_FIRST, NULL))
{
TRACE0("뷰 창을 만들지 못했습니다.\n");
return -1;
}
if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
{
TRACE0("도구 모음을 만들지 못했습니다.\n");
return -1; // 만들지 못했습니다.
}
if (!m_wndStatusBar.Create(this) ||
!m_wndStatusBar.SetIndicators(indicators,
sizeof(indicators)/sizeof(UINT)))
{
TRACE0("상태 표시줄을 만들지 못했습니다.\n");
return -1; // 만들지 못했습니다.
}
// TODO: 도구 모음을 도킹할 수 없게 하려면 이 세 줄을 삭제하십시오.
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndToolBar);
return 0;
}
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
if( !CFrameWnd::PreCreateWindow(cs) )
return FALSE;
// TODO: CREATESTRUCT cs를 수정하여 여기에서
// Window 클래스 또는 스타일을 수정합니다.
cs.dwExStyle &= ~WS_EX_CLIENTEDGE;
cs.lpszClass = AfxRegisterWndClass(0);
cs.cx = 512 + 4 *2;
cs.cy = 512 + 64 + 32;
return TRUE;
}
// CMainFrame 진단
#ifdef _DEBUG
void CMainFrame::AssertValid() const
{
CFrameWnd::AssertValid();
}
void CMainFrame::Dump(CDumpContext& dc) const
{
CFrameWnd::Dump(dc);
}
#endif //_DEBUG
// CMainFrame 메시지 처리기
void CMainFrame::OnSetFocus(CWnd* /*pOldWnd*/)
{
// 뷰 창으로 포커스를 이동합니다.
m_wndView.SetFocus();
}
BOOL CMainFrame::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
{
// 뷰에서 첫째 크랙이 해당 명령에 나타나도록 합니다.
if (m_wndView.OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
return TRUE;
// 그렇지 않으면 기본 처리합니다.
return CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
}
void CMainFrame::OnAppOpen()
{
FILE *read_fp;
time(&s_time);
read_fp = fopen("lena.raw", "rb");
//read_fp = fopen("lena(128x128).raw", "rb");
//read_fp = fopen("lena.raw", "rb");
if(read_fp == NULL)
{
AfxMessageBox(L"파일이 안보입니다만;;;", MB_OK, 0);
return;
}
// printf("No lena.raw file! Exit!\n"), exit(1);
fread(lena_origin, sizeof(unsigned char), SIZE * SIZE, read_fp);
fclose(read_fp);
OnAppView();
time(&e_time);
message.Format(L"수행시간 : %d초\n레나를 찾았음!", e_time - s_time);
AfxMessageBox(message, MB_OK, 0);
// TODO: 여기에 명령 처리기 코드를 추가합니다.
}
void CMainFrame::OnAppView()
{
// TODO: 여기에 명령 처리기 코드를 추가합니다.
int i, j;
CClientDC dc(this);
if(viewWhat == 1)
{
for (i = 0; i < SIZE; i++)
{
for (j = 0; j < SIZE; j++)
{
SetPixel(dc, j+2, i+26, RGB( lena_origin[i][j], lena_origin[i][j], lena_origin[i][j]));
}
}
}
else if (viewWhat == 2)
{
for (i = 0; i < SIZE; i++)
{
for (j = 0; j < SIZE; j++)
{
SetPixel(dc, j+2, i+26, RGB( lena_dct[i][j], lena_dct[i][j], lena_dct[i][j]));
}
}
}
else if (viewWhat == 3)
{
for (i = 0; i < SIZE; i++)
{
for (j = 0; j < SIZE; j++)
{
SetPixel(dc, j+2, i+26, RGB( lena_quant[i][j], lena_quant[i][j], lena_quant[i][j]));
}
}
}
else if (viewWhat == 4)
{
for (i = 0; i < SIZE; i++)
{
for (j = 0; j < SIZE; j++)
{
SetPixel(dc, j+2, i+26, RGB( lena_iquant[i][j], lena_iquant[i][j], lena_iquant[i][j]));
}
}
}
else if (viewWhat == 5)
{
for (i = 0; i < SIZE; i++)
{
for (j = 0; j < SIZE; j++)
{
SetPixel(dc, j+2, i+26, RGB( lena_idct[i][j], lena_idct[i][j], lena_idct[i][j]));
}
}
}
// TODO: 여기에 명령 처리기 코드를 추가합니다.
}
void DCT(int row, int column)
{
int i, j, u, v;
double cu, cv;
double lena_8x8[8][8]={0,};
for(i = 0; i < 8; i++)
{
for(j = 0; j < 8; j++)
{
if(i == 0) cu = 1 / sqrt(2.0);
else cu = 1;
if(j == 0) cv = 1 / sqrt(2.0);
else cv = 1;
for(u = 0; u < 8; u++)
{
for(v = 0; v < 8; v++)
{
lena_8x8[i][j] += (lena_origin[row + u][column + v])*cos(((2*u+1)*i*PI)/16)*cos(((2*v+1)*j*PI)/16);
}
}
lena_8x8[i][j] *= (cu * cv) / 4;
lena_temp[row + i][column + j] = lena_8x8[i][j];
if(lena_8x8[i][j] < 0)
{
lena_dct[row + i][column + j] = 0;
}
else if(lena_8x8[i][j] > 255)
{
lena_dct[row + i][column + j] = 255;
}
else
{
lena_dct[row + i][column + j] = (int)lena_8x8[i][j];
}
}
}
}
void iDCT(int row, int column)
{
int i, j, u, v;
double cu, cv;
double lena_8x8[8][8]={0,};
for(i = 0; i < 8; i++)
{
for(j = 0; j < 8; j++)
{
for(u = 0; u < 8; u++)
{
for(v = 0; v < 8; v++)
{
if(u == 0) cu = 1 / sqrt(2.0);
else cu = 1;
if(v == 0) cv = 1 / sqrt(2.0);
else cv = 1;
lena_8x8[i][j] += cu*cv*(lena_temp[row + u][column + v])*cos(((2*i+1)*u*PI)/16)*cos(((2*j+1)*v*PI)/16);
}
}
lena_8x8[i][j] /= 4;
if(lena_8x8[i][j] < 0)
{
lena_idct[row + i][column + j] = 0;
}
else if(lena_8x8[i][j] > 255)
{
lena_idct[row + i][column + j] = 255;
}
else
{
lena_idct[row + i][column + j] = (int)lena_8x8[i][j];
}
}
}
}
void Quantization(int row, int column)
{
int i, j;
for(i = 0; i < 8; i++)
{
for(j = 0; j < 8; j++)
{
lena_temp[row + i][column + j] = floor((lena_temp[row + i][column + j]/QuantMatrix[i][j]) + 0.5);
if(lena_temp[row + i][column + j] < 0)
{
lena_quant[row + i][column + j] = 0;
}
else if(lena_temp[row + i][column + j] > 255)
{
lena_quant[row + i][column + j] = 255;
}
else
{
lena_quant[row + i][column + j] = (int)lena_temp[row + i][column + j];
}
}
}
}
void iQuantization(int row, int column)
{
int i, j;
for(i = 0; i < 8; i++)
{
for(j = 0; j < 8; j++)
{
lena_temp[row + i][column + j] = lena_temp[row + i][column + j] * QuantMatrix[i][j];
if(lena_temp[row + i][column + j] < 0)
{
lena_iquant[row + i][column + j] = 0;
}
else if(lena_temp[row + i][column + j] > 255)
{
lena_iquant[row + i][column + j] = 255;
}
else
{
lena_iquant[row + i][column + j] = (int)lena_temp[row + i][column + j];
}
}
}
}
void CMainFrame::OnAppDct()
{
// TODO: 여기에 명령 처리기 코드를 추가합니다.
int i, j;
time(&s_time);
for(i = 0; i < SIZE; i += 8)
{
for(j = 0; j < SIZE; j += 8)
{
DCT(i, j);
}
}
viewWhat = 2;
OnAppView();
time(&e_time);
message.Format(L"수행시간 : %d초\nDCT 변환 성공!", e_time - s_time);
AfxMessageBox(message, MB_OK, 0);
viewWhat = 1;
// TODO: 여기에 명령 처리기 코드를 추가합니다.
}
void CMainFrame::OnAppidct()
{
int i, j;
time(&s_time);
for(i = 0; i < SIZE; i += 8)
{
for(j = 0; j < SIZE; j += 8)
{
iDCT(i, j);
}
}
viewWhat = 5;
OnAppView();
time(&e_time);
message.Format(L"수행시간 : %d초\niDCT 변환 성공!", e_time - s_time);
AfxMessageBox(message, MB_OK, 0);
viewWhat = 1;
// TODO: 여기에 명령 처리기 코드를 추가합니다.
}
void CMainFrame::OnAppQuant()
{
int i, j;
time(&s_time);
for(i = 0; i < SIZE; i += 8)
{
for(j = 0; j < SIZE; j += 8)
{
Quantization(i, j);
}
}
viewWhat = 3;
OnAppView();
time(&e_time);
message.Format(L"수행시간 : %d초\nQuantization 변환 성공!", e_time - s_time);
AfxMessageBox(message, MB_OK, 0);
viewWhat = 1;
// TODO: 여기에 명령 처리기 코드를 추가합니다.
}
void CMainFrame::OnAppiquant()
{
int i, j;
time(&s_time);
for(i = 0; i < SIZE; i += 8)
{
for(j = 0; j < SIZE; j += 8)
{
iQuantization(i, j);
}
}
viewWhat = 4;
OnAppView();
time(&e_time);
message.Format(L"수행시간 : %d초\nQuantization 변환 성공!", e_time - s_time);
AfxMessageBox(message, MB_OK, 0);
viewWhat = 1;
// TODO: 여기에 명령 처리기 코드를 추가합니다.
}
닫기