www.pudn.com > 32位 DIB 图形类.zip > JPEGAPI.cpp
#include "stdafx.h" #include "dibapi.h" #include "jpegapi.h" #include#include "Intel\IJL.h" #ifndef DIBIMAGE_NO_JPEG // byte offsets #define BO_BLUE 0 #define BO_GREEN 1 #define BO_RED 2 /************************************************************************* * * Function: ReadJPEGFile (CFile&) * * Purpose: Reads in the specified JPEG file into a global chunk of * memory. * * Returns: A handle to a dib (hDIB) if successful. * NULL if an error occurs. * * Comments: BITMAPFILEHEADER is stripped off of the DIB. * Everything from the end of the BITMAPFILEHEADER structure * on is returned in the global memory handle. * **************************************************************************/ HDIB ReadJPEGFile(CFile& file) { //For correct operation of the T2A macro, see MFC Tech Note 59 USES_CONVERSION; //Keep a local copy of the filename for usage with the IJL functions. //Note that since IJL does not support Unicode we must perform the //Unicode to Ascii conversion char lpszAsciiFileName[MAX_PATH]; TCHAR pszFileName[_MAX_PATH]; _tcscpy(pszFileName, file.GetFilePath()); strcpy(lpszAsciiFileName, T2A(pszFileName)); ASSERT(strlen(lpszAsciiFileName)); JPEG_CORE_PROPERTIES image; ZeroMemory(&image, sizeof(JPEG_CORE_PROPERTIES)); BYTE* pImageData; DWORD imageSize; TRY { //Init the IJL if (ijlInit(&image) != IJL_OK) { TRACE(_T("Cannot initialize Intel JPEG library!\n")); AfxThrowUserException(); } //Read in the Jpeg file parameters image.JPGFile = (LPTSTR) lpszAsciiFileName; //LPTSTR cast is required since the IJL //header files are prototyped to use a //LPTSTR even through Intel have currently //only released Ascii versions of IJL as of v1.0 if (ijlRead(&image, IJL_JFILE_READPARAMS) != IJL_OK) { TRACE(_T("Cannot read JPEG file header from %s file!\n"), image.JPGFile); AfxThrowUserException(); } //Allocate memory for the image int nChannels = 3; imageSize = image.JPGWidth*image.JPGHeight*nChannels; pImageData = new BYTE[imageSize]; if (pImageData == NULL) { TRACE(_T("Cannot allocate memory for image\n")); AfxThrowMemoryException(); } //Call the IJL to load the Jpeg from file image.DIBWidth = image.JPGWidth; image.DIBHeight = image.JPGHeight; image.DIBChannels = nChannels; image.DIBBytes = pImageData; if (ijlRead(&image, IJL_JFILE_READWHOLEIMAGE) != IJL_OK) { TRACE(_T("Cannot read image pImageData from %s file!\n"), image.JPGFile); delete [] pImageData; AfxThrowUserException(); } //Finished with IJL if (ijlFree(&image) != IJL_OK) TRACE(_T("Cannot free Intel(R) JPEG library!")); } CATCH_ALL(e) { ijlFree(&image); TRACE(_T("Error opening JPEG file!\n")); return NULL; } END_CATCH_ALL // initializing incapsulated image with correct values SIZE imageDims; imageDims.cx = image.JPGWidth; imageDims.cy = image.JPGHeight; BITMAPINFO bmi; BITMAPINFOHEADER& bih = bmi.bmiHeader; ZeroMemory(&bih, sizeof(BITMAPINFOHEADER)); bih.biSize = sizeof(BITMAPINFOHEADER); bih.biWidth = imageDims.cx; bih.biHeight = imageDims.cy; bih.biCompression = BI_RGB; bih.biPlanes = 1; bih.biBitCount = 24; //Allocate a buffer to use for the transfer to DIB format imageSize = imageDims.cy*(imageDims.cx*3+((4-((imageDims.cx*3)&3))&3)); BYTE* pBmp = new BYTE[imageSize]; if (pBmp == NULL) return NULL; //Copy the DIB bits from the user buffer into the DIB int lagDelta = ((4-((imageDims.cx*3)&3))&3); int lag = (imageDims.cy - 1)*lagDelta; for (int j=0; j biBitCount != 24) { TRACE(_T("Only 16 million colors (24 bit) images can be saved as JPEG!\n")); ::GlobalUnlock((HGLOBAL) hDib); return FALSE; } if (lpBI->biCompression != BI_RGB) { TRACE(_T("RLE-compressed images can't be saved as JPEG!\n")); ::GlobalUnlock((HGLOBAL) hDib); return FALSE; } DWORD dwDIBSize = *(LPDWORD)lpBI + ::PaletteSize((LPSTR)lpBI); // Partial Calculation // Now calculate the size of the image DWORD dwBmBitsSize; // Size of Bitmap Bits only // It's not RLE, so size is Width (DWORD aligned) * Height dwBmBitsSize = WIDTHBYTES((lpBI->biWidth)*((DWORD)lpBI->biBitCount)) * lpBI->biHeight; dwDIBSize += dwBmBitsSize; // Now, since we have calculated the correct size, why don't we // fill in the biSizeImage field (this will fix any .BMP files which // have this field incorrect). lpBI->biSizeImage = dwBmBitsSize; JPEG_CORE_PROPERTIES image; ZeroMemory(&image, sizeof(JPEG_CORE_PROPERTIES)); TRY { //Init the IJL if (ijlInit(&image) != IJL_OK) { TRACE(_T("Can't initialize Intel(R) JPEG library!\n")); AfxThrowUserException(); } image.jquality = dwQuality; // [0...100], best is 100 // LIB's default is 75, our default is 100 SIZE imageDims; imageDims.cx = lpBI->biWidth; imageDims.cy = lpBI->biHeight; // Setup DIB image.DIBWidth = imageDims.cx; image.DIBHeight = imageDims.cy; // Setup JPEG image.JPGFile = (LPTSTR) lpszAsciiFileName; //LPTSTR cast is required since the IJL //header files are prototyped to use a //LPTSTR even through Intel have currently //only released Ascii versions of IJL as of v1.0 image.JPGWidth = imageDims.cx; image.JPGHeight = imageDims.cy; pImageData = (BYTE*)lpBI + lpBI->biSize; //Allocate some memory to save the Dib bits into pBmp = new BYTE[dwDIBSize]; if (pBmp == NULL) { ::GlobalUnlock((HGLOBAL) hDib); return NULL; } //Copy the Dib bits into the buffer we just allocated int lag = 0; int lagDelta = ((4-((imageDims.cx*3)&3))&3); for (int j=0; j biSize]; if (pImageData == NULL) { delete [] pBmp; return NULL; } CopyMemory(pImageData, pBmp, dwDIBSize - lpBI->biSize); //upside-down, right? for (j=0; j