// PictureConvert.cpp: implementation of the CPictureConvert class. // ////////////////////////////////////////////////////////////////////// #include "PictureConvert.h" ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CPictureConvert::CPictureConvert() { GdiplusStartup(&m_gdiplusToken, &m_gdiplusStartupInput, NULL); GetCoderInfo(); } CPictureConvert::~CPictureConvert() { if(NULL != m_pImageCodecInfo) free(m_pImageCodecInfo); m_pImageCodecInfo = NULL; GdiplusShutdown(m_gdiplusToken); PictureRealFree(); } void CPictureConvert::GetCoderInfo(void) { m_pImageCodecInfo = NULL; m_nCoderNum = 0; unsigned int size = 0; GetImageEncodersSize(&m_nCoderNum, &size); if(size == 0) { m_nCoderNum = 0; return; } m_pImageCodecInfo = (ImageCodecInfo*)(malloc(size)); if(NULL == m_pImageCodecInfo) { m_nCoderNum = 0; return; } //获得系统中可用的编码方式的所有信息 if(GetImageEncoders(m_nCoderNum, size, m_pImageCodecInfo) != 0) { m_nCoderNum = 0; free(m_pImageCodecInfo); m_pImageCodecInfo = NULL; return; } } BOOL CPictureConvert::GetImageCLSID(const WCHAR*format, CLSID* pCLSID) {//得到格式为format的图像文件的编码值,访问该格式图像的COM组件的GUID值保存在pCLSID中 //在可用编码信息中查找format格式是否被支持 for(UINT i=0; iRelease(); return FALSE; } USES_CONVERSION; CLSID clImageClsid; if(convertMode == CONVERT_TO_JPG) { if(GetImageCLSID(A2W("image/jpeg"), &clImageClsid) == FALSE) { pStmSrc->Release(); delete imImage; return FALSE; } } else if(convertMode == CONVERT_TO_BMP) { if(GetImageCLSID(A2W("image/bmp"), &clImageClsid) == FALSE) { pStmSrc->Release(); delete imImage; return FALSE; } } else { pStmSrc->Release(); delete imImage; return FALSE; } if(imImage->Save(A2W(DestFileName), &clImageClsid) != 0) { pStmSrc->Release(); delete imImage; return FALSE; } pStmSrc->Release(); delete imImage; return TRUE; } BOOL CPictureConvert::ConvertPictrue(char *SrcFileName, char **pMemBuf, DWORD *MemBufSize, int convertMode) { if(NULL == SrcFileName || NULL != (*pMemBuf) || NULL == MemBufSize) return FALSE; CFile hSrcFile; try { hSrcFile.Open(SrcFileName, CFile::modeRead); } catch(...) { return FALSE; } DWORD fileLen = hSrcFile.GetLength(); HGLOBAL hMemSrc = GlobalAlloc(GPTR, fileLen); if(NULL == hMemSrc) { hSrcFile.Close(); return FALSE; } BYTE *pSrcBuf = (BYTE *)GlobalLock(hMemSrc); hSrcFile.ReadHuge(pSrcBuf, fileLen); GlobalUnlock(hMemSrc); hSrcFile.Close(); IStream *pStmSrc = NULL; CreateStreamOnHGlobal(hMemSrc, TRUE, &pStmSrc); if(NULL == pStmSrc) { GlobalFree(hMemSrc); return FALSE; } Image *imImage = NULL; imImage = Image::FromStream(pStmSrc, FALSE); if(NULL == imImage) { pStmSrc->Release(); return FALSE; } USES_CONVERSION; CLSID clImageClsid; if(convertMode == CONVERT_TO_JPG) { if(GetImageCLSID(A2W("image/jpeg"), &clImageClsid) == FALSE) { pStmSrc->Release(); delete imImage; return FALSE; } } else if(convertMode == CONVERT_TO_BMP) { if(GetImageCLSID(A2W("image/bmp"), &clImageClsid) == FALSE) { pStmSrc->Release(); delete imImage; return FALSE; } } else { pStmSrc->Release(); delete imImage; return FALSE; } HGLOBAL hMemDst = GlobalAlloc(GMEM_MOVEABLE, 0); if(NULL == hMemDst) { pStmSrc->Release(); delete imImage; return FALSE; } IStream *pStmDst = NULL; CreateStreamOnHGlobal(hMemDst, TRUE, &pStmDst); if(NULL == pStmDst) { GlobalFree(hMemDst); pStmSrc->Release(); delete imImage; *pMemBuf = NULL; return FALSE; } if(imImage->Save(pStmDst, &clImageClsid) != 0) { pStmDst->Release(); pStmSrc->Release(); delete imImage; *pMemBuf = NULL; return FALSE; } (*MemBufSize) = GlobalSize(hMemDst); (*pMemBuf) = FindConvertMem((*MemBufSize)); if((*pMemBuf) == NULL) { PICTRUE_CONVERT_MEM *pCONVERT_MEM = NULL; (*pMemBuf) = (char *)malloc(*MemBufSize); pCONVERT_MEM = (PICTRUE_CONVERT_MEM *)malloc(sizeof(PICTRUE_CONVERT_MEM)); if(NULL == (*pMemBuf) || NULL == pCONVERT_MEM) { pStmDst->Release(); pStmSrc->Release(); delete imImage; *pMemBuf = NULL; return FALSE; } pCONVERT_MEM->nMemSize = (*MemBufSize); pCONVERT_MEM->pMem = (*pMemBuf); pCONVERT_MEM->useFlag = CONVERT_MEM_USED; m_vec_ConvertMem.push_back(pCONVERT_MEM); } BYTE *pDst = (BYTE *)GlobalLock(hMemDst); memcpy((*pMemBuf), pDst, (*MemBufSize)); GlobalUnlock(hMemDst); pStmDst->Release(); pStmSrc->Release(); delete imImage; return TRUE; } BOOL CPictureConvert::ConvertPictrue(char *BmpMemData, unsigned int BmpMemDataSize, unsigned int BmpWidth, unsigned int BmpHeight, char *JpgFileName) { if(NULL == BmpMemData || NULL == JpgFileName) return FALSE; BITMAPFILEHEADER fileheader; BITMAPINFOHEADER infoH; int bitCount = BmpMemDataSize/(BmpWidth*BmpHeight); DWORD fileLen = BmpMemDataSize+54; HGLOBAL hMemSrc = GlobalAlloc(GPTR, fileLen); if(NULL == hMemSrc) { return FALSE; } memset(&fileheader, 0, sizeof(BITMAPFILEHEADER)); fileheader.bfType = 19778;//固定为'BM' fileheader.bfSize = fileLen; fileheader.bfOffBits = 54; infoH.biSize = sizeof(BITMAPINFOHEADER); infoH.biWidth = BmpWidth; infoH.biHeight = BmpHeight; infoH.biPlanes = 1; infoH.biBitCount = bitCount*8; infoH.biCompression = BI_RGB; infoH.biSizeImage = BmpMemDataSize; infoH.biXPelsPerMeter = 0; infoH.biYPelsPerMeter = 0; infoH.biClrUsed = 0; infoH.biClrImportant = 0; BYTE *pSrcBuf = (BYTE *)GlobalLock(hMemSrc); memcpy(pSrcBuf, &fileheader, 14); memcpy(pSrcBuf+14, &infoH, 40); memcpy(pSrcBuf+54, BmpMemData, BmpMemDataSize); GlobalUnlock(hMemSrc); IStream *pStmSrc = NULL; CreateStreamOnHGlobal(hMemSrc, TRUE, &pStmSrc); if(NULL == pStmSrc) { GlobalFree(hMemSrc); return FALSE; } Image *imImage = NULL; imImage = Image::FromStream(pStmSrc, FALSE); if(NULL == imImage) { pStmSrc->Release(); return FALSE; } USES_CONVERSION; CLSID clImageClsid; if(GetImageCLSID(A2W("image/jpeg"), &clImageClsid) == FALSE) { pStmSrc->Release(); delete imImage; return FALSE; } if(imImage->Save(A2W(JpgFileName), &clImageClsid) != 0) { pStmSrc->Release(); delete imImage; return FALSE; } pStmSrc->Release(); delete imImage; return TRUE; } BOOL CPictureConvert::ConvertPictrue(char *BmpMemData, unsigned int BmpMemDataSize, unsigned int BmpWidth, unsigned int BmpHeight, char **JpgMemData, DWORD *JpgMemBufSize) { if(NULL == BmpMemData || NULL != (*JpgMemData) || NULL == JpgMemBufSize) return FALSE; BITMAPFILEHEADER fileheader; BITMAPINFOHEADER infoH; DWORD fileLen = BmpMemDataSize+54; HGLOBAL hMemSrc = GlobalAlloc(GPTR, fileLen); if(NULL == hMemSrc) { return FALSE; } memset(&fileheader, 0, sizeof(BITMAPFILEHEADER)); fileheader.bfType = 19778;//固定为'BM' fileheader.bfSize = fileLen; fileheader.bfOffBits = 54; infoH.biSize = sizeof(BITMAPINFOHEADER); infoH.biWidth = BmpWidth; infoH.biHeight = BmpHeight; infoH.biPlanes = 1; infoH.biBitCount = (BmpMemDataSize/(BmpWidth*BmpHeight))*8; infoH.biCompression = BI_RGB; infoH.biSizeImage = BmpMemDataSize; infoH.biXPelsPerMeter = 0; infoH.biYPelsPerMeter = 0; infoH.biClrUsed = 0; infoH.biClrImportant = 0; BYTE *pSrcBuf = (BYTE *)GlobalLock(hMemSrc); memcpy(pSrcBuf, &fileheader, 14); memcpy(pSrcBuf+14, &infoH, 40); memcpy(pSrcBuf+54, BmpMemData, BmpMemDataSize); GlobalUnlock(hMemSrc); IStream *pStmSrc = NULL; CreateStreamOnHGlobal(hMemSrc, TRUE, &pStmSrc); if(NULL == pStmSrc) { GlobalFree(hMemSrc); return FALSE; } Image *imImage = NULL; imImage = Image::FromStream(pStmSrc, FALSE); if(NULL == imImage) { pStmSrc->Release(); return FALSE; } USES_CONVERSION; CLSID clImageClsid; if(GetImageCLSID(A2W("image/jpeg"), &clImageClsid) == FALSE) { pStmSrc->Release(); delete imImage; return FALSE; } HGLOBAL hMemDst = GlobalAlloc(GMEM_MOVEABLE, 0); if(NULL == hMemDst) { pStmSrc->Release(); delete imImage; return FALSE; } IStream *pStmDst = NULL; CreateStreamOnHGlobal(hMemDst, TRUE, &pStmDst); if(NULL == pStmDst) { GlobalFree(hMemDst); pStmSrc->Release(); delete imImage; *JpgMemData = NULL; return FALSE; } if(imImage->Save(pStmDst, &clImageClsid) != 0) { pStmDst->Release(); pStmSrc->Release(); delete imImage; *JpgMemData = NULL; return FALSE; } (*JpgMemBufSize) = GlobalSize(hMemDst); (*JpgMemData) = FindConvertMem((*JpgMemBufSize)); if((*JpgMemData) == NULL) { PICTRUE_CONVERT_MEM *pCONVERT_MEM = NULL; (*JpgMemData) = (char *)malloc(*JpgMemBufSize); pCONVERT_MEM = (PICTRUE_CONVERT_MEM *)malloc(sizeof(PICTRUE_CONVERT_MEM)); if(NULL == (*JpgMemData) || NULL == pCONVERT_MEM) { pStmDst->Release(); pStmSrc->Release(); delete imImage; *JpgMemData = NULL; return FALSE; } pCONVERT_MEM->nMemSize = (*JpgMemBufSize); pCONVERT_MEM->pMem = (*JpgMemData); pCONVERT_MEM->useFlag = CONVERT_MEM_USED; m_vec_ConvertMem.push_back(pCONVERT_MEM); } BYTE *pDst = (BYTE *)GlobalLock(hMemDst); memcpy((*JpgMemData), pDst, (*JpgMemBufSize)); GlobalUnlock(hMemDst); pStmDst->Release(); pStmSrc->Release(); delete imImage; return TRUE; } BOOL CPictureConvert::ConvertPictrue(char *JpgMemData, DWORD JpgMemSize, char *BmpFileName) { if(NULL == JpgMemData || NULL == BmpFileName) return FALSE; DWORD fileLen = JpgMemSize; HGLOBAL hMemSrc = GlobalAlloc(GPTR, fileLen); if(NULL == hMemSrc) { return FALSE; } BYTE *pSrcBuf = (BYTE *)GlobalLock(hMemSrc); memcpy(pSrcBuf, JpgMemData, JpgMemSize); GlobalUnlock(hMemSrc); IStream *pStmSrc = NULL; CreateStreamOnHGlobal(hMemSrc, TRUE, &pStmSrc); if(NULL == pStmSrc) { GlobalFree(hMemSrc); return FALSE; } Image *imImage = NULL; imImage = Image::FromStream(pStmSrc, FALSE); if(NULL == imImage) { pStmSrc->Release(); return FALSE; } USES_CONVERSION; CLSID clImageClsid; if(GetImageCLSID(A2W("image/bmp"), &clImageClsid) == FALSE) { pStmSrc->Release(); delete imImage; return FALSE; } if(imImage->Save(A2W(BmpFileName), &clImageClsid) != 0) { pStmSrc->Release(); delete imImage; return FALSE; } pStmSrc->Release(); delete imImage; return TRUE; } BOOL CPictureConvert::ConvertPictrue(char *JpgMemData, DWORD JpgMemSize, char **BmpMemData, DWORD *MemBufSize) { if(NULL == JpgMemData || NULL != (*BmpMemData) || NULL == MemBufSize) return FALSE; DWORD fileLen = JpgMemSize; HGLOBAL hMemSrc = GlobalAlloc(GPTR, fileLen); if(NULL == hMemSrc) { return FALSE; } BYTE *pSrcBuf = (BYTE *)GlobalLock(hMemSrc); memcpy(pSrcBuf, JpgMemData, JpgMemSize); GlobalUnlock(hMemSrc); IStream *pStmSrc = NULL; CreateStreamOnHGlobal(hMemSrc, TRUE, &pStmSrc); if(NULL == pStmSrc) { GlobalFree(hMemSrc); return FALSE; } Image *imImage = NULL; imImage = Image::FromStream(pStmSrc, FALSE); if(NULL == imImage) { pStmSrc->Release(); return FALSE; } USES_CONVERSION; CLSID clImageClsid; if(GetImageCLSID(A2W("image/bmp"), &clImageClsid) == FALSE) { pStmSrc->Release(); delete imImage; return FALSE; } HGLOBAL hMemDst = GlobalAlloc(GMEM_MOVEABLE, 0); if(NULL == hMemDst) { pStmSrc->Release(); delete imImage; return FALSE; } IStream *pStmDst = NULL; CreateStreamOnHGlobal(hMemDst, TRUE, &pStmDst); if(NULL == pStmDst) { GlobalFree(hMemDst); pStmSrc->Release(); delete imImage; *BmpMemData = NULL; return FALSE; } if(imImage->Save(pStmDst, &clImageClsid) != 0) { pStmDst->Release(); pStmSrc->Release(); delete imImage; *BmpMemData = NULL; return FALSE; } (*MemBufSize) = GlobalSize(hMemDst); (*BmpMemData) = FindConvertMem((*MemBufSize)); if((*BmpMemData) == NULL) { PICTRUE_CONVERT_MEM *pCONVERT_MEM = NULL; (*BmpMemData) = (char *)malloc(*MemBufSize); pCONVERT_MEM = (PICTRUE_CONVERT_MEM *)malloc(sizeof(PICTRUE_CONVERT_MEM)); if(NULL == (*BmpMemData) || NULL == pCONVERT_MEM) { pStmDst->Release(); pStmSrc->Release(); delete imImage; *BmpMemData = NULL; return FALSE; } pCONVERT_MEM->nMemSize = (*MemBufSize); pCONVERT_MEM->pMem = (*BmpMemData); pCONVERT_MEM->useFlag = CONVERT_MEM_USED; m_vec_ConvertMem.push_back(pCONVERT_MEM); } BYTE *pDst = (BYTE *)GlobalLock(hMemDst); memcpy((*BmpMemData), pDst, (*MemBufSize)); GlobalUnlock(hMemDst); pStmDst->Release(); pStmSrc->Release(); delete imImage; return TRUE; } void CPictureConvert::PictureMemFree(char **MemData) { CONVERT_MEM_VEC::iterator it_beg = m_vec_ConvertMem.begin(); CONVERT_MEM_VEC::iterator it_end = m_vec_ConvertMem.end(); for(; it_beg!=it_end; it_beg++) { if((*it_beg)->pMem == (*MemData)) { (*MemData) = NULL; (*it_beg)->useFlag = CONVERT_MEM_NONE; break; } } } void CPictureConvert::PictureRealFree(void) { CONVERT_MEM_VEC::iterator it_beg = m_vec_ConvertMem.begin(); CONVERT_MEM_VEC::iterator it_end = m_vec_ConvertMem.end(); for(; it_beg!=it_end; it_beg++) { free((*it_beg)->pMem); (*it_beg)->pMem = NULL; delete (*it_beg); } m_vec_ConvertMem.clear(); } char *CPictureConvert::FindConvertMem(DWORD size) { CONVERT_MEM_VEC::iterator it_beg = m_vec_ConvertMem.begin(); CONVERT_MEM_VEC::iterator it_end = m_vec_ConvertMem.end(); for(; it_beg!=it_end; it_beg++) { if((*it_beg)->useFlag == CONVERT_MEM_NONE && (*it_beg)->nMemSize >= size) { (*it_beg)->useFlag = CONVERT_MEM_USED; return (*it_beg)->pMem; } } return NULL; }