ComImage

// #include "StdAfx.h"
#include  < Windows.h >
#include 
< stdlib.h >
#include 
< stdio.h >
#include 
" ComImage.h "
#include 
" ComFun.h "

HANDLE DDBToDIB(HBITMAP hBitmap, HPALETTE hPalette, BITMAPINFO 
*  pOutDibInfo,  int  nBitpPix)
{
    BITMAP            BM;
    BITMAPINFOHEADER    BMinfoh;
    BITMAPINFO 
*         pBMinfo;
    HPALETTE        hPalOld 
=  NULL;
    DWORD            dwLenDib, dwBmInfoLen;
    HANDLE            hDIB;
    HDC             hDC;
    
int                 nColors;
    BOOL            bRetVal;
    
if (hBitmap  ==  NULL)
    {
        ::SetLastError(ERROR_INVALID_HANDLE);
        
return  NULL;
    }
    
if  (hPalette == NULL)
        hPalette 
=  (HPALETTE)::GetStockObject(DEFAULT_PALETTE);
    GetObject(hBitmap, 
sizeof (BITMAP), (LPVOID) & BM);
    BMinfoh.biSize            
=   sizeof (BITMAPINFOHEADER);
    BMinfoh.biWidth            
=  BM.bmWidth;
    BMinfoh.biHeight         
=  BM.bmHeight;
    BMinfoh.biPlanes         
=   1 ;         // Must 1
     if (nBitpPix  ==   0 )
        BMinfoh.biBitCount        
=  BM.bmPlanes  *  BM.bmBitsPixel;
    
else
        BMinfoh.biBitCount        
=  BM.bmPlanes  *  nBitpPix;
    BMinfoh.biCompression    
=  BI_RGB;
    BMinfoh.biSizeImage        
=   0 ;
    BMinfoh.biXPelsPerMeter    
=   0 ;
    BMinfoh.biYPelsPerMeter    
=   0 ;
    BMinfoh.biClrUsed        
=   0 ;
    BMinfoh.biClrImportant    
=   0 ;
    
if (BMinfoh.biBitCount  >   8 )        nColors  =   0 ;
    
else                             nColors  =   1   <<  BMinfoh.biBitCount;
    dwBmInfoLen  
=  BMinfoh.biSize  +  nColors  *   sizeof (RGBQUAD);
    hDC 
=  GetDC(NULL);
    
if (hPalette)
    {
        hPalOld 
=  SelectPalette(hDC, hPalette, FALSE);
        RealizePalette(hDC);
    }

    pBMinfo 
=  (BITMAPINFO  * )GlobalAlloc(GMEM_FIXED, dwBmInfoLen);
    
if (pBMinfo  ==  NULL)
    {
        SelectPalette(hDC, hPalOld, FALSE);
        ReleaseDC(NULL, hDC);
        ::SetLastError(ERROR_NOT_ENOUGH_MEMORY);
        
return  NULL;
    }
    memcpy(
& pBMinfo -> bmiHeader,  & BMinfoh,  sizeof (BITMAPINFOHEADER));
    GetDIBits(hDC, hBitmap, 
0 , BMinfoh.biHeight, NULL, pBMinfo, DIB_RGB_COLORS);
    
if  (pBMinfo -> bmiHeader.biSizeImage  ==   0 )
    {
        pBMinfo
-> bmiHeader.biSizeImage  =  ((((pBMinfo -> bmiHeader.biWidth  *  pBMinfo -> bmiHeader.biBitCount)  +   31 &   ~ 31 /   8
            
*  pBMinfo -> bmiHeader.biHeight;
    }
    dwLenDib 
=  dwBmInfoLen  +  pBMinfo -> bmiHeader.biSizeImage;
    hDIB 
=  GlobalAlloc(GMEM_FIXED, dwLenDib);
    
if  (hDIB  ==  NULL)
    {
        GlobalFree(pBMinfo);
        
if (hPalOld)    SelectPalette(hDC, hPalOld, FALSE);
        ReleaseDC(NULL, hDC);
        
return  NULL;
    }
    memcpy(hDIB, pBMinfo, 
sizeof (BITMAPINFOHEADER));
    bRetVal 
=  GetDIBits(hDC, hBitmap,  0 , BMinfoh.biHeight,
        (LPBYTE)hDIB 
+  (BMinfoh.biSize  +  nColors  *   sizeof (RGBQUAD)),
        pBMinfo, DIB_RGB_COLORS);
    
if ( bRetVal  ==  FALSE )
    {
        GlobalFree(hDIB);
        GlobalFree(pBMinfo);
        
if (hPalOld)    SelectPalette(hDC, hPalOld, FALSE);
        ReleaseDC(NULL, hDC);
        
return  NULL;
    }
    
if (pOutDibInfo  !=  NULL)
        memcpy(pOutDibInfo, pBMinfo, dwBmInfoLen);
    GlobalFree(pBMinfo);
    
if (hPalOld)    SelectPalette(hDC, hPalOld, FALSE);
    ReleaseDC(NULL, hDC);
    
return  hDIB;
}

BOOL SaveDIBToBMP(HANDLE hDib, CHAR 
*  pFileName)
{
    BITMAPFILEHEADER    BmFileHead;
    BITMAPINFOHEADER 
*     pBmInfoHead;
    
int                     nColors;
    HANDLE                hFile;
    DWORD                dwWrite;
    DWORD                dwDibSize;
    
if  ( ! hDib)
    {
        ::SetLastError(ERROR_INVALID_HANDLE);
        
return  FALSE;
    }
    hFile 
=  CreateFileA(pFileName, GENERIC_WRITE,  0 , NULL, CREATE_ALWAYS,
        FILE_ATTRIBUTE_NORMAL 
|  FILE_FLAG_SEQUENTIAL_SCAN, NULL);
    
if  (hFile  ==  INVALID_HANDLE_VALUE)
    {
        
return  FALSE;
    }
    pBmInfoHead 
=  (BITMAPINFOHEADER  * )hDib;
    
if (pBmInfoHead -> biBitCount  >   8 )        nColors  =   0 ;
    
else                                 nColors  =   1   <<  pBmInfoHead -> biBitCount;
    dwDibSize 
=  pBmInfoHead -> biSize  +  nColors * sizeof (RGBQUAD)  +  pBmInfoHead -> biSizeImage;
    BmFileHead.bfType        
=  ((WORD) ( ' M '   <<   8 |   ' B ' );     // "BM"
    BmFileHead.bfSize         =  dwDibSize  +   sizeof (BITMAPFILEHEADER);
    BmFileHead.bfReserved1    
=   0 ;
    BmFileHead.bfReserved2    
=   0 ;
    BmFileHead.bfOffBits    
=  (DWORD) ( sizeof ( BITMAPFILEHEADER )  +  pBmInfoHead -> biSize  +  nColors  *   sizeof (RGBQUAD));
    WriteFile(hFile, 
& BmFileHead,  sizeof (BITMAPFILEHEADER),  & dwWrite, NULL);
    WriteFile(hFile, hDib,        dwDibSize,                
& dwWrite, NULL);
    CloseHandle(hFile);
    
return  TRUE;
}

BOOL SaveBitmapToFile(HBITMAP hBitmap, CHAR 
*  pFileName)
{
    HANDLE        hDib 
=  NULL;
    HPALETTE    hPalette 
=  NULL;
    BOOL        bRetVal;
    hDib 
=  DDBToDIB(hBitmap, hPalette);
    
if (hDib  ==  NULL)
    {
        
return  FALSE;
    }
    bRetVal 
=  SaveDIBToBMP(hDib, pFileName);
    GlobalFree(hDib);
    
return  bRetVal;
}

HANDLE GetDIBFromWindow(HWND hWnd, RECT 
*  pWndRect)
{
    HANDLE        hDib;
    HBITMAP        hBitmap, hOldBitmap;
    HDC            hWndDc, hMemDc;
    RECT        WndRect;
    
int             nWidth, nHeigh;
    hWndDc 
=  ::GetWindowDC(hWnd);
    hMemDc 
=  ::CreateCompatibleDC(hWndDc); 
    
if  (pWndRect  ==  NULL)
    {
        
if (hWnd  ==  HWND_DESKTOP)
        {
            nWidth    
=  GetSystemMetrics(SM_CXSCREEN);
            nHeigh    
=  GetSystemMetrics(SM_CYSCREEN);
        }
        
else
        {
            ::GetWindowRect(hWnd, 
& WndRect);
            nWidth 
=  WndRect.right  -  WndRect.left;
            nHeigh 
=  WndRect.bottom  -  WndRect.top;
        }
    }
    
else
    {
        nWidth 
=  pWndRect -> right  -  pWndRect -> left;
        nHeigh 
=  pWndRect -> bottom  -  pWndRect -> top;
    }

    hBitmap 
=  ::CreateCompatibleBitmap(hWndDc, nWidth, nHeigh);
    hOldBitmap 
=  (HBITMAP)::SelectObject(hMemDc, hBitmap);
    BitBlt(hMemDc, 
0 0 , nWidth, nHeigh, hWndDc,  0 0 , SRCCOPY);
    hDib 
=  DDBToDIB(hBitmap);
    ::SelectObject(hMemDc, hOldBitmap);
    ::DeleteObject(hBitmap);
    ::DeleteDC(hMemDc);
    ::ReleaseDC(hWnd, hWndDc);
    
return  hDib;
}

BOOL SaveWindowToBMP(CHAR 
*  pBMPName, HWND hWnd, RECT  *  pWndRect)
{
    HANDLE    hDib;
    ::ShowWindow(hWnd, SW_SHOW);
    ::BringWindowToTop(hWnd);
    ::UpdateWindow(hWnd);
    hDib 
=  GetDIBFromWindow(hWnd, pWndRect);
    SaveDIBToBMP(hDib, pBMPName);
    GlobalFree(hDib);
    
return  TRUE;
}

BOOL GetBitmapSize(HBITMAP hBitmap, DWORD 
*  pdwBmInfoSize, DWORD  *  pdwDIBSize,  int  nBit)
{
    BITMAP                BM;
    
int                     nRetVal, nColors, nBitpPix;
    
if (hBitmap  ==  NULL)
    {
        ::SetLastError(ERROR_INVALID_HANDLE);
        
return  FALSE;
    }
    nRetVal 
=  GetObject(hBitmap,  sizeof (BITMAP), (LPVOID) & BM);
    
if (nRetVal  !=   sizeof (BITMAP))
    {
        Msgerr(
" GetObject " );
        
return  FALSE;
    }
    
if (nBit  !=   0 )    nBitpPix     =  nBit;
    
else             nBitpPix     =  BM.bmBitsPixel;
    nColors 
=   1    <<   nBitpPix;
    
if (nBitpPix  <=   8 )
        
* pdwBmInfoSize  =   sizeof (BITMAPINFOHEADER)  +  nColors * sizeof (RGBQUAD);
    
else      // 无调色板
         * pdwBmInfoSize  =   sizeof (BITMAPINFOHEADER);
    
* pdwDIBSize  =   * pdwBmInfoSize  +  ((BM.bmWidth  *  nBitpPix  + 31 /   32 *   4   *  BM.bmHeight;
    
return  TRUE;
}

BOOL SaveHiconToICOFile(HICON hIcon, CHAR 
*  pFileName,  int  nBit)
{
    ICONHEADER        IconHead;
    ICONDIRENTRY    IconDir;
    ICONINFO        IconInfo;
    HANDLE            hFile;
    VOID 
*             pColorDIB;
    VOID 
*             pMaskDIB;
    BITMAPINFO 
*     pColorInfo;
    BITMAPINFO 
*     phMaskInfo;
    DWORD    dwColorInfoSize, dwMaskInfoSize;
    DWORD    dwColorDIBSize,  dwMaskDIBSize;
    DWORD            dwWrite;
    BOOL            bRetVal;

    
if (hIcon  ==  NULL  ||  pFileName  ==  NULL)
    {
        SetLastError(ERROR_INVALID_HANDLE);
        
return  FALSE;
    }
    
if (nBit  !=   0   &&  nBit  !=   1   &&  nBit  !=   4   &&  nBit  !=   5   &&  
        nBit 
!=   16   &&  nBit  !=   32 )
    {
        SetLastError(ERROR_INVALID_HANDLE);
        
return  FALSE;
    }
    hFile 
=  CreateFileA(pFileName, GENERIC_WRITE,  0 , NULL, CREATE_ALWAYS,
        FILE_ATTRIBUTE_NORMAL 
|  FILE_FLAG_SEQUENTIAL_SCAN, NULL);
    
if  (hFile  ==  INVALID_HANDLE_VALUE)
    {
        
return  FALSE;
    }
    memset(
& IconHead,  0 sizeof (IconHead));
    memset(
& IconDir,  0 sizeof (IconDir));
    GetIconInfo(hIcon,  
& IconInfo);

    GetBitmapSize(IconInfo.hbmColor, 
& dwColorInfoSize,  & dwColorDIBSize, nBit);
    GetBitmapSize(IconInfo.hbmColor, 
& dwMaskInfoSize,   & dwMaskDIBSize,   1 );
    pColorInfo    
=  (BITMAPINFO  * )malloc(dwColorInfoSize);  
    phMaskInfo    
=  (BITMAPINFO  * )malloc(dwMaskInfoSize); 
    
if (pColorInfo  ==  NULL  ||  phMaskInfo  ==  NULL)
    {
        ::SetLastError(ERROR_NOT_ENOUGH_MEMORY);
        
return  NULL;
    }
    memset(pColorInfo, 
0 , dwColorInfoSize);
    memset(phMaskInfo, 
0 , dwMaskInfoSize);
    pColorDIB    
=  DDBToDIB(IconInfo.hbmColor, NULL, pColorInfo,  0 );
    pMaskDIB    
=  DDBToDIB(IconInfo.hbmMask,  NULL, phMaskInfo,  1 );     // 单色蒙板

    IconHead.idReserved    
=   0 ;
    IconHead.idType        
=   1 ;
    IconHead.idCount    
=   1 ;         // 一个图标
    IconDir.bWidth         =  (BYTE)pColorInfo -> bmiHeader.biWidth;
    IconDir.bHeight        
=  (BYTE)pColorInfo -> bmiHeader.biHeight;
    IconDir.bColorCount    
=  pColorInfo -> bmiHeader.biPlanes   *   pColorInfo -> bmiHeader.biBitCount;
    IconDir.dwBytesInRes    
=  dwColorDIBSize   +   dwMaskDIBSize  -  dwMaskInfoSize;
    IconDir.dwImageOffset    
=   sizeof (IconHead)   +    sizeof (IconDir);
    bRetVal 
&=  WriteFile(hFile,  & IconHead,  sizeof (IconHead),  & dwWrite, NULL);
    bRetVal 
&=  WriteFile(hFile,  & IconDir,   sizeof (IconDir),   & dwWrite, NULL);
    pColorInfo
-> bmiHeader.biHeight         *=   2 ;     // Color + Mask
    pColorInfo -> bmiHeader.biSizeImage     +=  dwMaskDIBSize  -  dwMaskInfoSize;
    bRetVal 
&=  WriteFile(hFile, pColorInfo, dwColorInfoSize,  & dwWrite, NULL);
    bRetVal 
&=  WriteFile(hFile, (BYTE  * )pColorDIB  +  dwColorInfoSize, dwColorDIBSize  -  dwColorInfoSize,  & dwWrite, NULL);
    bRetVal 
&=  WriteFile(hFile, (BYTE  * )pMaskDIB   +  dwMaskInfoSize,  dwMaskDIBSize   -  dwMaskInfoSize,   & dwWrite, NULL);
    
    
//  Ben: WriteFile() do the correct thing, but return 0, so:
    DWORD nErr;
    nErr 
=  GetLastError();
    bRetVal 
=  ( 0   ==  nErr)  ?  TRUE:FALSE;

    free(pColorInfo);
    free(phMaskInfo);
    GlobalFree(pColorDIB);    
// for DDBToDIB
    GlobalFree(pMaskDIB);
    DeleteObject(IconInfo.hbmColor);
    DeleteObject(IconInfo.hbmMask);
    CloseHandle(hFile);
    
return   bRetVal;
}

DWORD DibMaskFill(HANDLE hDib, HANDLE hMaskDib, COLORREF Color)
{
    BITMAPINFO 
*     pColorInfo;
    BITMAPINFO 
*     phMaskInfo;
    pColorInfo 
=  (BITMAPINFO  * )hDib;
    phMaskInfo 
=  (BITMAPINFO  * )hMaskDib;
    
if (phMaskInfo -> bmiHeader.biBitCount  >   2 )     //     蒙板 不是单色
    {
        
return   0 ;
    }
    
return   0 ;
}

HBITMAP GetHiconBitmap(HICON hIcon, COLORREF Color)
{
    ICONINFO    IconInfo;
    BITMAP        BM;
    HBITMAP        hBitmap, hBitmapOld1, hBitmapOld2;
    BOOL        bRetVal 
=  TRUE;
    HDC        hmDC, hMemDc1, hMemDc2;
    hmDC    
=  GetDC(NULL);
    hMemDc1    
=  CreateCompatibleDC(hmDC);
    hMemDc2    
=  CreateCompatibleDC(hmDC);
    
if (GetIconInfo(hIcon,  & IconInfo)  ==  FALSE)
    {
        Msgerr(
" GetIconInfo Error! " );
        
return  NULL;
    }
    GetObject(IconInfo.hbmColor, 
sizeof (BITMAP),  & BM);
    hBitmap 
=  CreateBitmap(BM.bmWidth, BM.bmHeight, BM.bmPlanes, BM.bmBitsPixel, NULL);
    hBitmapOld1 
=  (HBITMAP)::SelectObject(hMemDc1, hBitmap);
    hBitmapOld2 
=  (HBITMAP)::SelectObject(hMemDc2, IconInfo.hbmColor);
    FloodFill(hMemDc1, 
0 0 , Color);
    bRetVal 
=  MaskBlt(hMemDc1,  0 0 , BM.bmWidth, BM.bmHeight, hMemDc2,  0 0 , IconInfo.hbmMask,  0 0 0xCCAA0000 );
    
if (bRetVal  ==  FALSE)
    {
        Msgerr(
" MaskBlt Error " );
        
return  NULL;
    }
    ::SelectObject(hMemDc1, hBitmapOld1);
    ::SelectObject(hMemDc2, hBitmapOld2);
    DeleteObject(IconInfo.hbmColor);
    DeleteObject(IconInfo.hbmMask);
    DeleteDC(hMemDc1);
    DeleteDC(hMemDc2);
    ::ReleaseDC(NULL, hmDC);
    
return  hBitmap;
}

#ifdef USEJPEGLIB

BOOL SaveBitmapToJPG(HBITMAP hBitMap, CHAR 
*  pJPGName,  int  nQuality)
{
    HANDLE        hDib 
=  NULL;
    HPALETTE    hPalette 
=  NULL;
    BOOL        bRetVal;
    hDib 
=  DDBToDIB(hBitMap, hPalette);
    
if (hDib  ==  NULL)
    {
        
return  FALSE;
    }
    bRetVal 
=  JpegFromDib(hDib, nQuality, pJPGName);
    GlobalFree(hDib);
    
return  bRetVal;
}

RGBQUAD QuadFromWord(WORD b16)
{
    BYTE bytVals[] 
=
    {
        
0 ,   16 24 32 ,   40 48 56 64 ,
            
72 80 88 96 104 , 112 , 120 , 128 ,
            
136 , 144 , 152 , 160 , 168 , 176 , 184 , 192 ,
            
200 , 208 , 216 , 224 , 232 , 240 , 248 , 255
    };
    WORD wR 
=  b16;
    WORD wG 
=  b16;
    WORD wB 
=  b16;
    RGBQUAD rgb;
    wR 
<<=   1 ; wR  >>=   11 ;
    wG 
<<=   6 ; wG  >>=   11 ;
    wB 
<<=   11 ; wB  >>=   11 ;
    rgb.rgbReserved 
=   0 ;
    rgb.rgbBlue     
=  bytVals[wB];
    rgb.rgbGreen    
=  bytVals[wG];
    rgb.rgbRed      
=  bytVals[wR];
    
return  rgb;
}

BOOL DibToSamps(HANDLE hDib, 
int  nSampsPerRow,  struct  jpeg_compress_struct cinfo,
    JSAMPARRAY jsmpPixels)
{
    
// Sanity...
     if  (hDib  ==  NULL  ||  nSampsPerRow  <=   0
    { 
        ::SetLastError(ERROR_INVALID_HANDLE);
        
return  FALSE; 
    } 
    
int  r = 0 , p = 0 , q = 0 , b = 0 , n = 0
        nUnused
= 0 , nBytesWide = 0 , nUsed = 0 , nLastBits = 0 , nLastNibs = 0 , nCTEntries = 0 ,
        nRow
= 0 , nByte = 0 , nPixel = 0 ;
    BYTE bytCTEnt
= 0 ;
    LPBITMAPINFOHEADER pbBmHdr
=  (LPBITMAPINFOHEADER)hDib;  // The bit count tells you the format of the bitmap:  // Decide how many entries will be in the color table (if any) 
     switch  (pbBmHdr -> biBitCount)
    {
    
case   1 :
        nCTEntries 
=   2 ;    // Monochrome
         break ;
    
case   4 :
        nCTEntries 
=   16 ;   // 16-color
         break ;
    
case   8 :
        nCTEntries 
=   256 // 256-color
         break ;
    
case   16 :
    
case   24 :
    
case   32 :
        nCTEntries 
=   0 ;    // No color table needed
         break ;
    
default :
        ::SetLastError(ERROR_INVALID_HANDLE);
        
return  FALSE;  // Unsupported format
    }

    DWORD     dwCTab 
=  (DWORD)pbBmHdr  +  pbBmHdr -> biSize;
    LPRGBQUAD pCTab  
=  (LPRGBQUAD)(dwCTab);
    LPSTR     lpBits 
=  (LPSTR)pbBmHdr  +
        (WORD)pbBmHdr
-> biSize  +     (WORD)(nCTEntries  *   sizeof (RGBQUAD));

    
// Different formats for the image bits
    LPBYTE   lpPixels  =  (LPBYTE)  lpBits;
    RGBQUAD
*  pRgbQs    =  (RGBQUAD * )lpBits;
    WORD
*     wPixels   =  (WORD * )   lpBits;

    
// Set up the jsamps according to the bitmap's format.
    
// Note that rows are processed bottom to top, because
    
// that's how bitmaps are created.
     switch  (pbBmHdr -> biBitCount)
    {
    
case   1 :
        nUsed      
=  (pbBmHdr -> biWidth  +   7 /   8 ;
        nUnused    
=  (((nUsed  +   3 /   4 *   4 -  nUsed;
        nBytesWide 
=  nUsed  +  nUnused;
        nLastBits  
=   8   -  ((nUsed  *   8 -  pbBmHdr -> biWidth);

        
for  (r = 0 ; r  <  pbBmHdr -> biHeight; r ++ )
        {
            
for  (p = 0 , q = 0 ; p  <  nUsed; p ++
            { 
                nRow
= (pbBmHdr -> biHeight - r - 1 *  nBytesWide;
                nByte 
=   nRow  +  p;
                
int  nBUsed  =  (p  <  (nUsed  >>   1 ) )  ?   8  : nLastBits;
                
//                                         ^^        Not sure about this symbol Might be problem               
                 for (b = 0 ; b  <  nBUsed;b ++
                { 
                    bytCTEnt 
=  lpPixels[nByte]  <<  b; 
                    bytCTEnt 
=  bytCTEnt  >>   7 ;

                    jsmpPixels[r][q
+ 0 =  pCTab[bytCTEnt].rgbRed;
                    jsmpPixels[r][q
+ 1 =  pCTab[bytCTEnt].rgbGreen;
                    jsmpPixels[r][q
+ 2 =  pCTab[bytCTEnt].rgbBlue;

                    q 
+=   3 ;
                }
            }
        }
        
break ;

    
case   4 :
        nUsed      
=  (pbBmHdr -> biWidth  +   1 /   2 ;
        nUnused    
=  (((nUsed  +   3 /   4 *   4 -  nUsed;
        nBytesWide 
=  nUsed  +  nUnused;
        nLastNibs  
=   2   -  ((nUsed  *   2 -  pbBmHdr -> biWidth);

        
for  (r = 0 ; r  <  pbBmHdr -> biHeight;r ++ )
        {
            
for  (p = 0 ,q = 0 ; p  <  nUsed;p ++
            { 
                nRow
= (pbBmHdr -> biHeight - r - 1 *  nBytesWide;
                nByte 
=  nRow  +  p;

                
int  nNibbles  =  (p   >>  ( 4 -  (n  *   4 )) );
                jsmpPixels[r][q
+ 0 =  pCTab[bytCTEnt].rgbRed;
                jsmpPixels[r][q
+ 1 =  pCTab[bytCTEnt].rgbGreen;
                jsmpPixels[r][q
+ 2 =  pCTab[bytCTEnt].rgbBlue;
                q 
+=   3 ;
            }
        }
        
break ;

    
default :
    
case   8 // Each byte is a pointer to a pixel color
        nUnused  =  (((pbBmHdr -> biWidth  +   3 /   4 *   4 -
            pbBmHdr
-> biWidth;

        
for  (r = 0 ;r  <  pbBmHdr -> biHeight; r ++ )
        {
            
for  (p = 0 ,q = 0 ; p  <  pbBmHdr -> biWidth; p ++ ,q += 3 )
            {
                nRow   
=  (pbBmHdr -> biHeight - r - 1 *  (pbBmHdr -> biWidth  +  nUnused);
                nPixel 
=   nRow  +  p;

                jsmpPixels[r][q
+ 0 =  pCTab[lpPixels[nPixel]].rgbRed;
                jsmpPixels[r][q
+ 1 =  pCTab[lpPixels[nPixel]].rgbGreen;
                jsmpPixels[r][q
+ 2 =  pCTab[lpPixels[nPixel]].rgbBlue;
            }
        }
        
break ;

    
case   16 // Hi-color (16 bits per pixel)
         for  (r = 0 ;r  <  pbBmHdr -> biHeight; r ++ )
        {
            
for  (p = 0 ,q = 0 ; p  <  pbBmHdr -> biWidth; p ++ ,q += 3 )
            {
                nRow    
=  (pbBmHdr -> biHeight - r - 1 *  pbBmHdr -> biWidth;
                nPixel  
=  nRow  +  p;

                RGBQUAD quad 
=  QuadFromWord(wPixels[nPixel]);

                jsmpPixels[r][q
+ 0 =  quad.rgbRed;
                jsmpPixels[r][q
+ 1 =  quad.rgbGreen;
                jsmpPixels[r][q
+ 2 =  quad.rgbBlue;
            }
        }
        
break ;

    
case   24 :
        nBytesWide 
=   (pbBmHdr -> biWidth * 3 );
        nUnused    
=   (((nBytesWide  +   3 /   4 *   4 -
            nBytesWide;
        nBytesWide 
+=  nUnused;

        
for  (r = 0 ; r  <  pbBmHdr -> biHeight; r ++ )
        {
            
for  (p = 0 ,q = 0 ;p  <  (nBytesWide - nUnused); p += 3 ,q += 3 )
            { 
                nRow 
=  (pbBmHdr -> biHeight - r - 1 *  nBytesWide;
                nPixel  
=  nRow  +  p;

                jsmpPixels[r][q
+ 0 =  lpPixels[nPixel + 2 ];  // Red
                jsmpPixels[r][q + 1 =  lpPixels[nPixel + 1 ];  // Green
                jsmpPixels[r][q + 2 =  lpPixels[nPixel + 0 ];  // Blue
            }
        }
        
break ;

    
case   32 :
        
for  (r = 0 ; r  <  pbBmHdr -> biHeight; r ++ )
        {
            
for  (p = 0 ,q = 0 ; p  <  pbBmHdr -> biWidth; p ++ ,q += 3 )
            {
                nRow    
=  (pbBmHdr -> biHeight - r - 1 *
                    pbBmHdr
-> biWidth;
                nPixel  
=  nRow  +  p;

                jsmpPixels[r][q
+ 0 =  pRgbQs[nPixel].rgbRed;
                jsmpPixels[r][q
+ 1 =  pRgbQs[nPixel].rgbGreen;
                jsmpPixels[r][q
+ 2 =  pRgbQs[nPixel].rgbBlue;
            }
        }
        
break ;
    }   
// end switch
     return  TRUE;
}

BOOL JpegFromDib(HANDLE hDib, 
int  nQuality, CHAR  *  pJPGName)
{
    BOOL    bRetVal;
    
int         nError;
    
// Basic sanity checks...
     if  (nQuality  <   0   ||  nQuality  >   100   ||  hDib    ==  NULL)
    {
        ::SetLastError(ERROR_INVALID_HANDLE);
        
return  FALSE;
    }
    
byte   * buf2  =   0 ;
    
// Use libjpeg functions to write scanlines to disk in JPEG format
    jpeg_compress_struct  *  pcinfo  =  (jpeg_compress_struct  * )malloc( sizeof (jpeg_compress_struct)  *   4 );
    memset(pcinfo, 
0 sizeof (jpeg_compress_struct)  *   4 );     // WARNING    jpeg_start_compress OVER
     struct  jpeg_error_mgr       jerr;

    FILE
*       pOutFile;      // Target file 
     int         nSampsPerRow;  // Physical row width in image buffer 
    JSAMPARRAY jsmpArray;     // Pixel RGB buffer for JPEG file
    pcinfo -> err  =  jpeg_std_error( & jerr);  // Use default error handling (ugly!)

    jpeg_create_compress(pcinfo);

    pOutFile 
=  fopen(pJPGName,  " wb " );
    
if  (pOutFile  ==  NULL)
    {
        nError 
=  ::GetLastError();
        jpeg_destroy_compress(pcinfo);
        ::SetLastError(nError);
        free(pcinfo);
        
return  FALSE;
    }

    jpeg_stdio_dest(pcinfo, pOutFile);

    LPBITMAPINFOHEADER lpbi 
=  (LPBITMAPINFOHEADER)hDib;

    pcinfo
-> image_width       =  lpbi -> biWidth;   // Image width and height, in pixels 
    pcinfo -> image_height      =  lpbi -> biHeight;
    pcinfo
-> input_components  =   3 ;               // Color components per pixel
    
// (RGB_PIXELSIZE - see jmorecfg.h)
    pcinfo -> in_color_space    =  JCS_RGB;           // Colorspace of input image

    jpeg_set_defaults(pcinfo);
    jpeg_set_quality(pcinfo, nQuality, TRUE);    
// Limit to baseline-JPEG values
    jpeg_start_compress(pcinfo, TRUE);

    
// JSAMPLEs per row in output buffer
    nSampsPerRow  =  pcinfo -> image_width  *  pcinfo -> input_components; 

    
// Allocate array of pixel RGB values
    jsmpArray  =  ( * pcinfo -> mem -> alloc_sarray)
        ((j_common_ptr) pcinfo,    JPOOL_IMAGE, nSampsPerRow, pcinfo
-> image_height);
    bRetVal 
=  DibToSamps(hDib, nSampsPerRow,  * pcinfo, jsmpArray);
    
if (bRetVal  ==  FALSE)
    {
        nError 
=  ::GetLastError();
        jpeg_finish_compress(pcinfo); 
// Always finish
        fclose(pOutFile);
        jpeg_destroy_compress(pcinfo); 
// Free resources
        free(pcinfo);
        ::SetLastError(nError);
        
return  FALSE;
    }
    
// Write the array of scan lines to the JPEG file
    jpeg_write_scanlines(pcinfo, jsmpArray, pcinfo -> image_height);
    jpeg_finish_compress(pcinfo); 
// Always finish
    fclose(pOutFile);
    jpeg_destroy_compress(pcinfo); 
// Free resources
    free(pcinfo);
    
return  TRUE;
}

#endif

/*
//  Bmp转换为Ico格式,  nBit为色彩位数,  支持位数如下:
//  0,  1,  4,  8,  16,  24,  32
//-------------------------
void  Bmp2Ico(String  strBmpFileName,  int  nBit)
{
    int  nIconWidth    =  GetSystemMetrics(SM_CXICON);
    int  nIconHeight  =  GetSystemMetrics(SM_CYICON);;
    Graphics::TBitmap  *MyBmp  =  new  Graphics::TBitmap();
    MyBmp->LoadFromFile(strBmpFileName);
    Graphics::TBitmap  *AndMask  =  new  Graphics::TBitmap();
    AndMask->Width    =  nIconWidth;
    AndMask->Height  =  nIconHeight;
    AndMask->Canvas->Brush->Color  =  clBlack;
    AndMask->Canvas->Rectangle(0,  0,  nIconWidth,  nIconHeight);
    Graphics::TBitmap  *XorMask  =  new  Graphics::TBitmap();
    XorMask->Width    =  nIconWidth;
    XorMask->Height  =  nIconHeight;
    StretchBlt(XorMask->Canvas->Handle,  0,  0,  nIconWidth,  nIconHeight,
        MyBmp->Canvas->Handle,  0,  0,  MyBmp->Width,  MyBmp->Height,  SRCCOPY);
    TIcon  *pIcon  =  new  TIcon();
    TIconInfo  IconInfo;
    IconInfo.fIcon  =  true;
    IconInfo.xHotspot  =  0;
    IconInfo.yHotspot  =  0;
    IconInfo.hbmMask    =  AndMask->Handle;
    IconInfo.hbmColor  =  XorMask->Handle;
    pIcon->Handle  =  CreateIconIndirect(&IconInfo);
    delete  AndMask;
    delete  XorMask;
    delete  MyBmp;
    String  strIcoFileName  =  ChangeFileExt(strBmpFileName,  ".ico");
    SaveIcon(pIcon->Handle,  strIcoFileName.c_str(),  nBit);
    delete  pIcon;
}
*/
 
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值