www.pudn.com > ±ÏÒµÁôÄî²á.rar > Jpeg.cpp


#include "stdafx.h" 
#include  
 
#include "Jpeg.h" 
 
#ifdef __cplusplus 
	extern "C" { 
#endif  
 
#include "jpeglib.h" 
 
#ifdef __cplusplus 
	} 
#endif  
#include  
 
#ifdef _DEBUG 
#undef THIS_FILE 
static char THIS_FILE[]=__FILE__; 
#define new DEBUG_NEW 
#endif 
 
struct my_error_mgr { 
  struct jpeg_error_mgr pub;	 
 
  jmp_buf setjmp_buffer;	 
}; 
 
typedef struct my_error_mgr * my_error_ptr; 
 
METHODDEF(void) my_error_exit (j_common_ptr cinfo); 
 
METHODDEF(void) my_error_exit (j_common_ptr cinfo) 
{ 
	my_error_ptr myerr = (my_error_ptr) cinfo->err; 
 
	char buffer[JMSG_LENGTH_MAX]; 
	(*cinfo->err->format_message) (cinfo, buffer); 
 
	MessageBox(GetActiveWindow(),buffer,"JPEG Fatal Error",MB_ICONSTOP); 
 
	longjmp(myerr->setjmp_buffer, 1); 
} 
 
void j_putRGBScanline(BYTE *jpegline,  
						 int widthPix, 
						 BYTE *outBuf, 
						 int row); 
 
void j_putGrayScanlineToRGB(BYTE *jpegline,  
						 int widthPix, 
						 BYTE *outBuf, 
						 int row); 
CJpeg::CJpeg() 
{ 
	m_strJPEGError = "No Error";  
	m_pDib = NULL; 
} 
 
CJpeg::CJpeg(CMidDib *pDib) 
{ 
	m_strJPEGError = "No Error";  
	m_pDib = NULL; 
	SetDib(pDib); 
} 
 
CJpeg::~CJpeg() 
{ 
	if (m_pDib != NULL) 
		delete m_pDib; 
} 
 
void CJpeg::FreeBuffer(BYTE *Buffer) 
{ 
	delete[] Buffer; 
} 
 
CString CJpeg::GetErrorString() 
{ 
	return m_strJPEGError; 
} 
BOOL CJpeg::Load(LPCSTR lpstrFileName) 
{ 
	UINT uWidth, uHeight, uWidthDW; 
	BYTE *lpTmpBuffer = ReadJPEGFile(lpstrFileName, &uWidth, &uHeight); 
	if (lpTmpBuffer == NULL) 
		return FALSE; 
	BGRFromRGB(lpTmpBuffer, uWidth, uHeight); 
	BYTE *lpBuffer = MakeDwordAlign(lpTmpBuffer, uWidth, uHeight, &uWidthDW); 
	FreeBuffer(lpTmpBuffer); 
	VertFlipBuf(lpBuffer, uWidthDW, uHeight); 
 
	BITMAPINFOHEADER bmiHeader; 
	bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 
	bmiHeader.biWidth = uWidth; 
	bmiHeader.biHeight = uHeight; 
	bmiHeader.biPlanes = 1; 
	bmiHeader.biBitCount = 24; 
	bmiHeader.biCompression = BI_RGB; 
	bmiHeader.biSizeImage = 0; 
	bmiHeader.biXPelsPerMeter = 0; 
	bmiHeader.biYPelsPerMeter = 0; 
	bmiHeader.biClrUsed = 0; 
	bmiHeader.biClrImportant = 0; 
 
	DWORD dwHeaderSize = sizeof(BITMAPINFOHEADER); 
	DWORD dwBitsSize = WIDTHBYTES(uWidth*24) * uHeight; 
    HDIB hDIB = GlobalAlloc(GHND, dwHeaderSize + dwBitsSize);  
	if (hDIB == NULL) 
		return FALSE; 
 
    LPBYTE lpDIB = (LPBYTE)GlobalLock(hDIB);  
    memcpy(lpDIB, (LPBYTE)&bmiHeader, dwHeaderSize);  
    memcpy(FindDIBBits((LPBYTE)lpDIB), lpBuffer, dwBitsSize);  
	FreeBuffer(lpBuffer); 
 
	if (m_pDib != NULL) 
		delete m_pDib; 
 
	m_pDib = new CMidDib(); 
	m_pDib->Attach(hDIB); 
 
	return TRUE; 
} 
 
BOOL CJpeg::Save(LPCSTR lpstrFileName, CMidDib* pDib, BOOL bColor, int nQuality) 
{ 
	if (pDib == NULL) 
		pDib = m_pDib; 
	if (pDib == NULL) 
		return FALSE; 
 
	HDIB hDib = CopyHandle(pDib->GetHandle()); 
	if (hDib == NULL) 
		return FALSE; 
 
	CMidDib* pDibTmp = new CMidDib; 
	pDibTmp->Attach(hDib); 
 
	if (pDibTmp->GetBitCount() != 24) 
		pDibTmp->ConvertFormat(24); 
 
	UINT uWidth  = pDibTmp->GetWidth(); 
	UINT uHeight = pDibTmp->GetHeight(); 
 
	BYTE* tmp = ClearDwordAlign(pDibTmp->GetBitsPtr(), 
									uWidth, 
									WIDTHBYTES(uWidth * 24), 
									uHeight); 
	if (tmp == NULL) 
		return FALSE; 
	BOOL bSuccess = WriteJPEGFile(lpstrFileName, 
							tmp, 
							uWidth,  
							uHeight, 
							bColor, 
							nQuality); 
 
	delete pDibTmp; 
	FreeBuffer(tmp); 
 
	return bSuccess; 
} 
 
BYTE * CJpeg::MakeDwordAlign(BYTE *dataBuf, 
								 UINT widthPix,			 
								 UINT height, 
								 UINT *uiOutWidthBytes)	 
{ 
	if (dataBuf==NULL) 
		return NULL; 
	UINT uiWidthBytes; 
	uiWidthBytes = WIDTHBYTES(widthPix * 24); 
 
	DWORD dwNewsize=(DWORD)((DWORD)uiWidthBytes *  
							(DWORD)height); 
	BYTE *pNew; 
	pNew=(BYTE *)new BYTE[dwNewsize]; 
	if (pNew==NULL) { 
		return NULL; 
	} 
	UINT uiInWidthBytes = widthPix * 3; 
	UINT uiCount; 
	for (uiCount=0;uiCount < height;uiCount++)  
	{ 
		BYTE * bpInAdd; 
		BYTE * bpOutAdd; 
		ULONG lInOff; 
		ULONG lOutOff; 
 
		lInOff=uiInWidthBytes * uiCount; 
		lOutOff=uiWidthBytes * uiCount; 
 
		bpInAdd= dataBuf + lInOff; 
		bpOutAdd= pNew + lOutOff; 
 
		memcpy(bpOutAdd,bpInAdd,uiInWidthBytes); 
	} 
 
	*uiOutWidthBytes=uiWidthBytes; 
	return pNew; 
} 
 
BOOL CJpeg::VertFlipBuf(BYTE* inbuf, UINT widthBytes, UINT height) 
{    
	BYTE  *tb1; 
	BYTE  *tb2; 
 
	if (inbuf==NULL) 
		return FALSE; 
 
	UINT bufsize; 
 
	bufsize=widthBytes; 
 
	tb1= (BYTE *)new BYTE[bufsize]; 
	if (tb1==NULL)  
	{ 
		return FALSE; 
	} 
 
	tb2= (BYTE *)new BYTE [bufsize]; 
	if (tb1==NULL)  
	{ 
		return FALSE; 
	} 
	 
	UINT row_cnt;      
	ULONG off1=0; 
	ULONG off2=0; 
 
	for (row_cnt=0;row_cnt<(height+1)/2;row_cnt++)  
	{ 
		off1=row_cnt*bufsize; 
		off2=((height-1)-row_cnt)*bufsize;    
		 
		memcpy(tb1,inbuf+off1,bufsize); 
		memcpy(tb2,inbuf+off2,bufsize);	 
		memcpy(inbuf+off1,tb2,bufsize); 
		memcpy(inbuf+off2,tb1,bufsize); 
	}	 
 
	delete [] tb1; 
	delete [] tb2; 
 
	return TRUE; 
}         
BOOL CJpeg::BGRFromRGB(BYTE *buf, UINT widthPix, UINT height) 
{ 
	if (buf==NULL) 
		return FALSE; 
 
	UINT col, row; 
	for (row=0;rowalloc_sarray) 
		((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1); 
	while (cinfo.output_scanline < cinfo.output_height)  
	{ 
	 
		(void) jpeg_read_scanlines(&cinfo, buffer, 1); 
	 
		if (cinfo.out_color_components==3)  
		{ 
			 
			j_putRGBScanline(buffer[0],  
							*uWidth, 
							dataBuf, 
							cinfo.output_scanline-1); 
 
		}  
		else if (cinfo.out_color_components==1)  
		{ 
 
		 
			j_putGrayScanlineToRGB(buffer[0],  
								*uWidth, 
								dataBuf, 
								cinfo.output_scanline-1); 
 
		} 
 
	} 
	(void) jpeg_finish_decompress(&cinfo); 
	jpeg_destroy_decompress(&cinfo);	 
	fclose(infile);	 
	return dataBuf; 
} 
 
BOOL CJpeg::WriteJPEGFile(LPCSTR lpstrFileName,  
						BYTE *dataBuf, 
						UINT widthPix, 
						UINT height, 
						BOOL color,  
						int quality) 
{ 
	if (dataBuf==NULL) 
		return FALSE; 
	if (widthPix==0) 
		return FALSE; 
	if (height==0) 
		return FALSE; 
 
	LPBYTE tmp; 
	if (!color)  
	{ 
		tmp = (BYTE*)new BYTE[widthPix*height]; 
		if (tmp==NULL)  
		{ 
			m_strJPEGError = "Memory error"; 
			return FALSE; 
		} 
 
		UINT row,col; 
		for (row=0;row