?? jpegdoc.cpp
字號(hào):
// JPEGDoc.cpp : implementation of the CJPEGDoc class
//
#include "stdafx.h"
#include "JPEG.h"
#include "math.h"
#include "JPEGDoc.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define PI (double)3.1415926535
unsigned char LumQuantTable[64]={ //luminance標(biāo)準(zhǔn)亮度量化表
/* 這一種量化效果太差,但是卻為多數(shù)標(biāo)準(zhǔn),為什么?
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
*/
///////////////////
//第二種效果較好,但是還是有點(diǎn)模糊
/////////////////////
0x8, 0x6, 0x6, 0x7, 0x6, 0x5, 0x8, 0x7,
0x7, 0x7, 0x9, 0x9, 0x8, 0xa, 0xc, 0x14,
0xd, 0xc, 0xb, 0xb, 0xc, 0x19,0x12,0x13,
0xf, 0x14,0x1d,0x1a,0x1f,0x1e,0x1d,0x1a,
0x1c,0x1c,0x20,0x24,0x2e,0x27,0x20,0x22,
0x2c,0x23,0x1c,0x1c,0x28,0x37,0x29,0x2c,
0x30,0x31,0x34,0x34,0x34,0x1f,0x27,0x39,
0x3d,0x38,0x32,0x3c,0x2e,0x33,0x34,0x32
};
unsigned char ChrQuantTable[64]={ //chrominance標(biāo)準(zhǔn)色度量化表
/*
17,18,24,47,99,99,99,99,
18,21,26,66,99,99,99,99,
24,26,56,99,99,99,99,99,
47,66,99,99,99,99,99,99,
99,99,99,99,99,99,99,99,
99,99,99,99,99,99,99,99,
99,99,99,99,99,99,99,99,
99,99,99,99,99,99,99,99
12,13,13,17,16,17,33,18,
18,33,69,46,39,46,69,69,
69,69,69,69,69,69,69,69,
69,69,69,69,69,69,69,69,
69,69,69,69,69,69,69,69,
69,69,69,69,69,69,69,69,
69,69,69,69,69,69,69,69,
69,69,69,69,69,69,69,69
/*
4, 5, 5, 8, 6, 8, 13,10,
10,13,39,26,19,26,49,49,
49,49,49,49,49,49,49,49,
49,49,49,49,49,49,49,49,
49,49,49,49,49,49,49,49,
49,49,49,49,49,49,49,49,
49,49,49,49,49,49,49,49,
49,49,49,49,49,49,49,49
*/
0x09,0x09,0x09,0x0c,0x0b,0x0c,0x18,0x0d,
0x0d,0x18,0x32,0x21,0x1c,0x21,0x32,0x32,
0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,
0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,
0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,
0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,
0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,
0x32,0x32,0x32,0x32,0x32,0x32,0x32,0x32,
};
unsigned char LumDCHuffmanBit[17]={0,0,1,5,1,1,1,1,1,1,0,0,0,0,0,0,0}; //亮度DC哈夫曼表的位值
unsigned char LumDCHuffmanVal[12]={0,1,2,3,4,5,6,7,8,9,10,11}; //亮度DC哈夫曼表的碼值
unsigned char LumACHuffmanBit[17]={0,0,2,1,3,3,2,4,3,5,5,4,4,0,0,1,0x7d}; //亮度AC哈夫曼表的位值
unsigned char LumACHuffmanVal[162]={ //亮度AC哈夫曼表的碼值
0x01,0x02,0x03,0x00,0x04,0x11,0x05,0x12,
0x21,0x31,0x41,0x06,0x13,0x51,0x61,0x07,
0x22,0x71,0x14,0x32,0x81,0x91,0xa1,0x08,
0x23,0x42,0xb1,0xc1,0x15,0x52,0xd1,0xf0,
0x24,0x33,0x62,0x72,0x82,0x09,0x0a,0x16,
0x17,0x18,0x19,0x1a,0x25,0x26,0x27,0x28,
0x29,0x2a,0x34,0x35,0x36,0x37,0x38,0x39,
0x3a,0x43,0x44,0x45,0x46,0x47,0x48,0x49,
0x4a,0x53,0x54,0x55,0x56,0x57,0x58,0x59,
0x5a,0x63,0x64,0x65,0x66,0x67,0x68,0x69,
0x6a,0x73,0x74,0x75,0x76,0x77,0x78,0x79,
0x7a,0x83,0x84,0x85,0x86,0x87,0x88,0x89,
0x8a,0x92,0x93,0x94,0x95,0x96,0x97,0x98,
0x99,0x9a,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,
0xa8,0xa9,0xaa,0xb2,0xb3,0xb4,0xb5,0xb6,
0xb7,0xb8,0xb9,0xba,0xc2,0xc3,0xc4,0xc5,
0xc6,0xc7,0xc8,0xc9,0xca,0xd2,0xd3,0xd4,
0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xe1,0xe2,
0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,
0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,
0xf9,0xfa
};
unsigned char ChrDCHuffmanBit[17]={0,0,3,1,1,1,1,1,1,1,1,1,0,0,0,0,0};
unsigned char ChrDCHuffmanVal[12]={0,1,2,3,4,5,6,7,8,9,10,11};
unsigned char ChrACHuffmanBit[17]={0,0,2,1,2,4,4,3,4,7,5,4,4,0,1,2,0x77};
unsigned char ChrACHuffmanVal[162]={
0x00,0x01,0x02,0x03,0x11,0x04,0x05,0x21,
0x31,0x06,0x12,0x41,0x51,0x07,0x61,0x71,
0x13,0x22,0x32,0x81,0x08,0x14,0x42,0x91,
0xa1,0xb1,0xc1,0x09,0x23,0x33,0x52,0xf0,
0x15,0x62,0x72,0xd1,0x0a,0x16,0x24,0x34,
0xe1,0x25,0xf1,0x17,0x18,0x19,0x1a,0x26,
0x27,0x28,0x29,0x2a,0x35,0x36,0x37,0x38,
0x39,0x3a,0x43,0x44,0x45,0x46,0x47,0x48,
0x49,0x4a,0x53,0x54,0x55,0x56,0x57,0x58,
0x59,0x5a,0x63,0x64,0x65,0x66,0x67,0x68,
0x69,0x6a,0x73,0x74,0x75,0x76,0x77,0x78,
0x79,0x7a,0x82,0x83,0x84,0x85,0x86,0x87,
0x88,0x89,0x8a,0x92,0x93,0x94,0x95,0x96,
0x97,0x98,0x99,0x9a,0xa2,0xa3,0xa4,0xa5,
0xa6,0xa7,0xa8,0xa9,0xaa,0xb2,0xb3,0xb4,
0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xc2,0xc3,
0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xd2,
0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,
0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,
0xea,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,
0xf9,0xfa
};
static const short zig[8*8]={ //Z型掃描的順序
0,1,5,6,14,15,27,28,
2,4,7,13,16,26,29,42,
3,8,12,17,25,30,41,43,
9,11,18,24,31,40,44,53,
10,19,23,32,39,45,52,54,
20,22,33,38,46,51,55,60,
21,34,37,47,50,56,59,61,
35,36,48,49,57,58,62,63
};
int ehufco[251],ehufsi[251];
#define WaitCursorBegin() HCURSOR hcURSOR = SetCursor(LoadCursor(NULL, IDC_WAIT))//定義為等待光標(biāo)
#define WaitCursorEnd() SetCursor(hcURSOR) //定義的等待光標(biāo)結(jié)束,回到默認(rèn)光標(biāo)
/////////////////////////////////////////////////////////////////////////////
// CJPEGDoc
IMPLEMENT_DYNCREATE(CJPEGDoc, CDocument)
BEGIN_MESSAGE_MAP(CJPEGDoc, CDocument)
//{{AFX_MSG_MAP(CJPEGDoc)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CJPEGDoc construction/destruction
CJPEGDoc::CJPEGDoc()
{
// TODO: add one-time construction code here
}
CJPEGDoc::~CJPEGDoc()
{
}
BOOL CJPEGDoc::OnNewDocument()
{
if (!CDocument::OnNewDocument())
return FALSE;
// TODO: add reinitialization code here
// (SDI documents will reuse this document)
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CJPEGDoc serialization
void CJPEGDoc::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{
// TODO: add storing code here
}
else
{
// TODO: add loading code here
}
}
CDib::CDib()
{
m_pDib=NULL; // 先設(shè)置DIB位圖指針為NULL,以便知道位圖是否被裝載
m_bit24=0; // 顏色數(shù)初值設(shè)為0
surplus=32; //
EncodeJpeg=0; //
height=0;
width=0;
for(int i=0;i<64;i++)
table[i]=0;
for(i=0;i<1600;i++)
{
data[i]=NULL;
hdata[i]=NULL;
}
}
CDib::~CDib()
{
// 如果位圖的指針不為空,將它刪除
if(m_pDib!=NULL)
delete [] m_pDib;
for(int i=0;i<1600;i++)
{
delete [] data[i];
delete [] hdata[i];
}
}
//////////////////////////////////////////////////////
//
//
//
//////////////////////////////////////////////////////
BOOL CDib::Load(const char *pszFilename)
{
CFile cf;
// 打開(kāi)一個(gè)名為pszFilename的位圖文件
if(!cf.Open(pszFilename,CFile::modeRead))
return(FALSE);
// 獲得文件的大小,并且減去BITMAPFILEHEADER結(jié)構(gòu),因?yàn)椴晃鏊惆阉粼趦?nèi)存中
DWORD dwDibSize;
BmpFileLength=cf.GetLength();
dwDibSize=BmpFileLength-sizeof(BITMAPFILEHEADER);
unsigned char *pDib;
pDib=new unsigned char [dwDibSize];
if(pDib==NULL)
return(FALSE);
BITMAPFILEHEADER BFH;
// 讀取文件的頭和數(shù)據(jù)
if(cf.Read(&BFH,sizeof(BITMAPFILEHEADER))!=sizeof(BITMAPFILEHEADER)||
BFH.bfType!='MB'||cf.Read(pDib,dwDibSize)!=dwDibSize) //MB為BMP文件的標(biāo)識(shí)符
{
// 如果出現(xiàn)錯(cuò)誤,釋放DIB位圖的存儲(chǔ)空間
delete [] pDib;
return(FALSE);
}
// 如果類(lèi)中的位圖指針不為空,釋放它
if(m_pDib!=NULL)
delete m_pDib;
// 將位圖結(jié)構(gòu)的指針和大小賦給成員變量
m_pDib=pDib;
m_dwDibSize=dwDibSize;
m_pBIH=(BITMAPINFOHEADER *)m_pDib;
m_pPalette=(RGBQUAD *)&m_pDib[sizeof(BITMAPINFOHEADER)];
// 計(jì)算調(diào)色板的顏色數(shù)目
m_nPaletteEntries=1<<m_pBIH->biBitCount;
if(m_pBIH->biBitCount>8)
m_nPaletteEntries=0;
else if(m_pBIH->biClrUsed!=0)
m_nPaletteEntries=m_pBIH->biClrUsed;
// 讓m_pDibBits指向?qū)嶋H的DIB位數(shù)據(jù)
m_pDibBits=&m_pDib[sizeof(BITMAPINFOHEADER)+m_nPaletteEntries*sizeof(RGBQUAD)];
// 如果有一個(gè)調(diào)色板,釋放它
if(m_Palette.GetSafeHandle()!=NULL)
m_Palette.DeleteObject();
// 創(chuàng)建調(diào)色板
if(m_nPaletteEntries!=0)
{
// 分配LOGPALETTE結(jié)構(gòu)的存儲(chǔ)空間
LOGPALETTE *pLogPal=(LOGPALETTE *)new char [sizeof(LOGPALETTE)+
m_nPaletteEntries*sizeof(PALETTEENTRY)];
if(pLogPal!=NULL)
{
// 設(shè)置調(diào)色板的版本為0x300,保存調(diào)色板的數(shù)目
pLogPal->palVersion=0x300;
pLogPal->palNumEntries=m_nPaletteEntries;
// 將RGB值放入每個(gè)PALETTEENTRY項(xiàng)
for(int i=0;i<m_nPaletteEntries;i++)
{
pLogPal->palPalEntry[i].peRed=m_pPalette[i].rgbRed;
pLogPal->palPalEntry[i].peGreen=m_pPalette[i].rgbGreen;
pLogPal->palPalEntry[i].peBlue=m_pPalette[i].rgbBlue;
}
// 創(chuàng)建調(diào)色板對(duì)象并刪除PALETTEENTRY的內(nèi)存
m_Palette.CreatePalette(pLogPal);
}
delete [] pLogPal;
}
// 如果是24位圖,設(shè)置m_bit24=1,并讀入位數(shù)據(jù)給data數(shù)組,不是24位圖,m_bit24=0
if(m_pBIH->biBitCount==8)
{
// AfxMessageBox("此文件不是24位的位圖文件夾!!!");
m_bit24=0;
}
else if(m_pBIH->biBitCount==24)
m_bit24=1;
width=m_pBIH->biWidth; //得到BMP文件的寬度
height=m_pBIH->biHeight; //得到BMP文件的高度
DWORD offset=BFH.bfOffBits; //得到BMP文件的數(shù)據(jù)偏移量
if(height>1600)
{
AfxMessageBox("本軟件目前只能處理高度小于等于1600BMP圖像,請(qǐng)確認(rèn)圖像!!!");
return(FALSE);
}
/* CString x;
x.Format("m_bit24=%d",m_bit24);
AfxMessageBox(x);
DWORD filesize=BFH.bfSize;
WORD type=BFH.bfType;
int first=type;
int second=type>>8;
CString st;
st.Format("BMP文件標(biāo)識(shí)符:%c%c 圖像寬度為:%ld 圖像高度為:%ld 偏移量為:%ld 文件大小:%ld字節(jié)",first,second,width,height,offset,filesize);
AfxMessageBox(st);
*/
LONG i,j;
if(m_bit24==1)
{
for(i=0;i<height;i++)
{
data[i]=new RGBData[width];
for(j=0;j<width;j++)
{
data[i][j].Blue=0;
data[i][j].Green=0;
data[i][j].Red=0;
}
}
cf.Seek(offset,CFile::begin); //定位至位數(shù)據(jù)的開(kāi)始處
for(LONG y=height-1;y>=0;y--)
{
cf.Read(data[y],width*3); //數(shù)組data存儲(chǔ)24位色BMP文件的圖像數(shù)據(jù)
cf.Seek(width%4,CFile::current); //***** 此處很重要,位圖行的字節(jié)數(shù)等于
} //行除以4乘以3,再加上行除以4的余。24位圖每象素3字節(jié)
cf.Close();
}
else if(m_bit24==0)
{
for(i=0;i<height;i++)
{
hdata[i]=new unsigned char [width];
for(j=0;j<width;j++)
hdata[i][j]=0;
}
cf.Seek(offset,CFile::begin); //定位至位數(shù)據(jù)的開(kāi)始處
// 從最后一行開(kāi)始讀數(shù)據(jù),BMP圖像文件依次從最后一行到第一行進(jìn)行存儲(chǔ)
for(LONG y=height-1;y>=0;y--)
{
cf.Read(hdata[y],width); //數(shù)組hdata存儲(chǔ)灰度圖像的數(shù)據(jù)
// cf.Seek(width%4,CFile::current); //灰度圖像不用考慮這種情況
}
cf.Close();
}
return(TRUE);
}
/*CFile類(lèi)
CFile與CArchive類(lèi)一起支持對(duì)MFC對(duì)象的串行化,常用的成員函數(shù)為:
Open函數(shù) 用一個(gè)錯(cuò)誤測(cè)試安全地打開(kāi)一個(gè)文件
Close函數(shù) 關(guān)閉一個(gè)文件并刪除該文件
Read函數(shù) 從文件的當(dāng)前位置處讀出一段數(shù)據(jù)給緩沖區(qū)
ReadHuge函數(shù) 從文件的當(dāng)前位置處讀出一段可大于64K的數(shù)據(jù)給緩沖區(qū)
Write函數(shù) 將一段數(shù)據(jù)寫(xiě)入文件的當(dāng)前位置處
WriteHuge函數(shù) 將一段可大于64K的數(shù)據(jù)寫(xiě)入文件的當(dāng)前位置處
Seek函數(shù) 用于定位當(dāng)前文件指針至任意處
GetLength函數(shù) 函數(shù)用一獲取文件長(zhǎng)(以字節(jié)計(jì))
*/
////////////////////////////////////////
//
// BMP文件的存儲(chǔ)
//
////////////////////////////////////////
BOOL CDib::Save(const char *pszFilename)
{
//如果沒(méi)有數(shù)據(jù),不能保存
if(m_pDib==NULL)
return(FALSE);
CFile cf;
if(!cf.Open(pszFilename,CFile::modeCreate|CFile::modeWrite))
return(FALSE);
BITMAPFILEHEADER BFH;
// 預(yù)設(shè)BITMAPFILEHEADER結(jié)構(gòu)的所有量全為0
memset(&BFH,0,sizeof(BITMAPFILEHEADER));
BFH.bfType='MB';
BFH.bfSize=sizeof(BITMAPFILEHEADER)+m_dwDibSize;
BFH.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+
m_nPaletteEntries*sizeof(RGBQUAD);
// 寫(xiě)具體數(shù)據(jù)到指定文件
cf.Write(&BFH,sizeof(BITMAPFILEHEADER));
cf.Write(m_pDib,m_dwDibSize);
return(TRUE);
}
/////////////////////////////////////////
//
// JPEG文件的存儲(chǔ)
//
/////////////////////////////////////////
BOOL CDib::SaveJpeg(const char *pszFilename)
{
WaitCursorBegin(); //顯示等待光標(biāo)
time_t tBegin, tEnd;
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -