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;row alloc_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