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; jbiBitCount != 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; jbiSize]; 
    if (pImageData == NULL)  
    { 
	    delete [] pBmp; 
	    return NULL; 
    } 
 
    CopyMemory(pImageData, pBmp, dwDIBSize - lpBI->biSize); 
 
    //upside-down, right? 
    for (j=0; j