
//********************************************************************** 
// 
//  dibutil.c 
// 
//  Source file for Device-Independent Bitmap (DIB) API.  Provides 
//  the following functions: 
// 
//  CreateDIB()         - Creates new DIB 
//  FindDIBBits()       - Sets pointer to the DIB bits 
//  DIBWidth()          - Gets the width of the DIB 
//  DIBHeight()         - Gets the height of the DIB 
//  PaletteSize()       - Calculates the buffer size required by a palette 
//  DIBNumColors()      - Calculates number of colors in the DIB's color table 
//  CreateDIBPalette()  - Creates a palette from a DIB 
//  DIBToBitmap()       - Creates a bitmap from a DIB 
//  BitmapToDIB()       - Creates a DIB from a bitmap 
//  PalEntriesOnDevice()- Gets the number of palette entries of a device 
//  GetSystemPalette()  - Returns a handle to the current system palette 
//  AllocRoomForDIB()   - Allocates memory for a DIB 
//  ChangeDIBFormat()   - Changes a DIB's BPP and/or compression format 
//  ChangeBitmapFormat()- Changes a bitmap to a DIB with specified BPP and 
//                        compression format 
// 
// Written by Microsoft Product Support Services, Developer Support. 
// Copyright 1991-1998 Microsoft Corporation. All rights reserved. 
//********************************************************************** 
 
#define     STRICT      // enable strict type checking 
#include "stdafx.h" 
#include <assert.h> 
#include "dibapi.h" 
#include "dibutil.h" 
#include <stdio.h> 
 
 
/************************************************************************* 
 * 
 * CreateDIB() 
 * 
 * Parameters: 
 * 
 * DWORD dwWidth    - Width for new bitmap, in pixels 
 * DWORD dwHeight   - Height for new bitmap  
 * WORD  wBitCount  - Bit Count for new DIB (1, 4, 8, or 24) 
 * 
 * Return Value: 
 * 
 * HDIB             - Handle to new DIB 
 * 
 * Description: 
 * 
 * This function allocates memory for and initializes a new DIB by 
 * filling in the BITMAPINFOHEADER, allocating memory for the color 
 * table, and allocating memory for the bitmap bits.  As with all 
 * HDIBs, the header, colortable and bits are all in one contiguous 
 * memory block.  This function is similar to the CreateBitmap()  
 * Windows API. 
 * 
 * The colortable and bitmap bits are left uninitialized (zeroed) in the 
 * returned HDIB. 
 * 
 * 
 ************************************************************************/ 
 
/*HDIB CreateDIB(DWORD dwWidth, DWORD dwHeight, WORD wBitCount) 
{ 
    BITMAPINFOHEADER    bi;             // bitmap header 
    LPBITMAPINFOHEADER  lpbi;           // pointer to BITMAPINFOHEADER 
    DWORD               dwLen;          // size of memory block 
    HDIB                hDIB; 
    DWORD               dwBytesPerLine; // Number of bytes per scanline 
 
 
    // Make sure bits per pixel is valid 
 
    if (wBitCount <= 1) 
        wBitCount = 1; 
    else if (wBitCount <= 4) 
        wBitCount = 4; 
    else if (wBitCount <= 8) 
        wBitCount = 8; 
    else if (wBitCount <= 24) 
        wBitCount = 24; 
    else 
        wBitCount = 4;  // set default value to 4 if parameter is bogus 
 
    // initialize BITMAPINFOHEADER 
 
    bi.biSize = sizeof(BITMAPINFOHEADER); 
    bi.biWidth = dwWidth;         // fill in width from parameter 
    bi.biHeight = dwHeight;       // fill in height from parameter 
    bi.biPlanes = 1;              // must be 1 
    bi.biBitCount = wBitCount;    // from parameter 
    bi.biCompression = BI_RGB;     
    bi.biSizeImage = 0;           // 0's here mean "default" 
    bi.biXPelsPerMeter = 0; 
    bi.biYPelsPerMeter = 0; 
    bi.biClrUsed = 0; 
    bi.biClrImportant = 0; 
 
    // calculate size of memory block required to store the DIB.  This 
    // block should be big enough to hold the BITMAPINFOHEADER, the color 
    // table, and the bits 
 
    dwBytesPerLine = WIDTHBYTES(wBitCount * dwWidth); 
    dwLen = bi.biSize + PaletteSize((LPSTR)&bi) + (dwBytesPerLine * dwHeight); 
 
    // alloc memory block to store our bitmap 
 
    hDIB = GlobalAlloc(GHND, dwLen); 
 
    // major bummer if we couldn't get memory block 
 
    if (!hDIB) 
        return NULL; 
 
    // lock memory and get pointer to it 
 
    lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB); 
 
    // use our bitmap info structure to fill in first part of 
    // our DIB with the BITMAPINFOHEADER 
 
    *lpbi = bi; 
 
    // Since we don't know what the colortable and bits should contain, 
    // just leave these blank.  Unlock the DIB and return the HDIB. 
 
    GlobalUnlock(hDIB); 
 
    //return handle to the DIB 
 
    return hDIB; 
} 
 */
 
/************************************************************************* 
 * 
 * FindDIBBits() 
 * 
 * Parameter: 
 * 
 * LPSTR lpDIB      - pointer to packed-DIB memory block 
 * 
 * Return Value: 
 * 
 * LPSTR            - pointer to the DIB bits 
 * 
 * Description: 
 * 
 * This function calculates the address of the DIB's bits and returns a 
 * pointer to the DIB bits. 
 * 
 ************************************************************************/ 
 
/*LPSTR FindDIBBits(LPSTR lpDIB) 
{ 
   return (lpDIB + *(LPDWORD)lpDIB + PaletteSize(lpDIB)); 
} */
 
 
/************************************************************************* 
 * 
 * DIBWidth() 
 * 
 * Parameter: 
 * 
 * LPSTR lpDIB      - pointer to packed-DIB memory block 
 * 
 * Return Value: 
 * 
 * DWORD            - width of the DIB 
 * 
 * Description: 
 * 
 * This function gets the width of the DIB from the BITMAPINFOHEADER 
 * width field if it is a Windows 3.0-style DIB or from the BITMAPCOREHEADER 
 * width field if it is an OS/2-style DIB. 
 * 
 ************************************************************************/ 
 
 
/*DWORD DIBWidth(LPSTR lpDIB) 
{ 
    LPBITMAPINFOHEADER   lpbmi;  // pointer to a Win 3.0-style DIB 
    LPBITMAPCOREHEADER   lpbmc;  // pointer to an OS/2-style DIB 
 
    // point to the header (whether Win 3.0 and OS/2) 
 
    lpbmi = (LPBITMAPINFOHEADER)lpDIB; 
    lpbmc = (LPBITMAPCOREHEADER)lpDIB; 
 
    // return the DIB width if it is a Win 3.0 DIB 
 
    if (lpbmi->biSize == sizeof(BITMAPINFOHEADER)) 
        return lpbmi->biWidth; 
    else  // it is an OS/2 DIB, so return its width 
        return (DWORD)lpbmc->bcWidth; 
} */
 
 
/************************************************************************* 
 * 
 * DIBHeight() 
 * 
 * Parameter: 
 * 
 * LPSTR lpDIB      - pointer to packed-DIB memory block 
 * 
 * Return Value: 
 * 
 * DWORD            - height of the DIB 
 * 
 * Description: 
 * 
 * This function gets the height of the DIB from the BITMAPINFOHEADER 
 * height field if it is a Windows 3.0-style DIB or from the BITMAPCOREHEADER 
 * height field if it is an OS/2-style DIB. 
 * 
 ************************************************************************/ 
 
/*DWORD DIBHeight(LPSTR lpDIB) 
{ 
   LPBITMAPINFOHEADER   lpbmi;  // pointer to a Win 3.0-style DIB 
   LPBITMAPCOREHEADER   lpbmc;  // pointer to an OS/2-style DIB 
 
   // point to the header (whether OS/2 or Win 3.0 
 
   lpbmi = (LPBITMAPINFOHEADER)lpDIB; 
   lpbmc = (LPBITMAPCOREHEADER)lpDIB; 
 
    // return the DIB height if it is a Win 3.0 DIB 
    if (lpbmi->biSize == sizeof(BITMAPINFOHEADER)) 
        return lpbmi->biHeight; 
    else  // it is an OS/2 DIB, so return its height 
        return (DWORD)lpbmc->bcHeight; 
} 
 
 
/************************************************************************* 
 * 
 * PaletteSize() 
 * 
 * Parameter: 
 * 
 * LPSTR lpDIB      - pointer to packed-DIB memory block 
 * 
 * Return Value: 
 * 
 * WORD             - size of the color palette of the DIB 
 * 
 * Description: 
 * 
 * This function gets the size required to store the DIB's palette by 
 * multiplying the number of colors by the size of an RGBQUAD (for a 
 * Windows 3.0-style DIB) or by the size of an RGBTRIPLE (for an OS/2- 
 * style DIB). 
 * 
 ***********************************************************************/ 
;WORD PaletteSize(LPSTR lpDIB) 
{ 
    // calculate the size required by the palette 
    if (IS_WIN30_DIB (lpDIB)) 
        return (DIBNumColors(lpDIB) * sizeof(RGBQUAD)); 
    else 
        return (DIBNumColors(lpDIB) * sizeof(RGBTRIPLE)); 
} 
 
 
/************************************************************************* 
 * 
 * DIBNumColors() 
 * 
 * Parameter: 
 * 
 * LPSTR lpDIB      - pointer to packed-DIB memory block 
 * 
 * Return Value: 
 * 
 * WORD             - number of colors in the color table 
 * 
 * Description: 
 * 
 * This function calculates the number of colors in the DIB's color table 
 * by finding the bits per pixel for the DIB (whether Win3.0 or OS/2-style 
 * DIB). If bits per pixel is 1: colors=2, if 4: colors=16, if 8: colors=256, 
 * if 24, no colors in color table. 
 * 
 **********************************************************************/ 
WORD DIBNumColors(LPSTR lpDIB) 
{ 
    WORD wBitCount;  // DIB bit count 
 
    // If this is a Windows-style DIB, the number of colors in the 
    // color table can be less than the number of bits per pixel 
    // allows for (i.e. lpbi->biClrUsed can be set to some value). 
    // If this is the case, return the appropriate value. 
     
 
    if (IS_WIN30_DIB(lpDIB)) 
    { 
        DWORD dwClrUsed; 
 
        dwClrUsed = ((LPBITMAPINFOHEADER)lpDIB)->biClrUsed; 
        if (dwClrUsed) 
 
        return (WORD)dwClrUsed; 
    } 
 
    // Calculate the number of colors in the color table based on 
    // the number of bits per pixel for the DIB. 
     
    if (IS_WIN30_DIB(lpDIB)) 
        wBitCount = ((LPBITMAPINFOHEADER)lpDIB)->biBitCount; 
    else 
        wBitCount = ((LPBITMAPCOREHEADER)lpDIB)->bcBitCount; 
 
    // return number of colors based on bits per pixel 
 
    switch (wBitCount) 
    { 
        case 1: 
            return 2; 
 
        case 4: 
            return 16; 
 
        case 8: 
            return 256; 
 
        default: 
            return 0; 
    } 
} 
 
 
/************************************************************************* 
 * 
 * CreateDIBPalette() 
 * 
 * Parameter: 
 * 
 * HDIB hDIB        - specifies the DIB 
 * 
 * Return Value: 
 * 
 * HPALETTE         - specifies the palette 
 * 
 * Description: 
 * 
 * This function creates a palette from a DIB by allocating memory for the 
 * logical palette, reading and storing the colors from the DIB's color table 
 * into the logical palette, creating a palette from this logical palette, 
 * and then returning the palette's handle. This allows the DIB to be 
 * displayed using the best possible colors (important for DIBs with 256 or 
 * more colors). 
 * 
 ************************************************************************/ 
/* 
HPALETTE CreateDIBPalette(HDIB hDIB) 
{ 
    LPLOGPALETTE        lpPal;          // pointer to a logical palette 
    HANDLE              hLogPal;        // handle to a logical palette 
    HPALETTE            hPal = NULL;    // handle to a palette 
    int                 i, wNumColors;  // loop index, number of colors in color table 
    LPSTR               lpbi;           // pointer to packed-DIB 
    LPBITMAPINFO        lpbmi;          // pointer to BITMAPINFO structure (Win3.0) 
    LPBITMAPCOREINFO    lpbmc;          // pointer to BITMAPCOREINFO structure (OS/2) 
    BOOL                bWinStyleDIB;   // Win3.0 DIB? 
 
    // if handle to DIB is invalid, return NULL 
 
    if (!hDIB) 
        return NULL; 
 
    // lock DIB memory block and get a pointer to it 
 
    lpbi = (char*)GlobalLock(hDIB); 
 
    // get pointer to BITMAPINFO (Win 3.0) 
 
    lpbmi = (LPBITMAPINFO)lpbi; 
 
    // get pointer to BITMAPCOREINFO (OS/2 1.x) 
 
    lpbmc = (LPBITMAPCOREINFO)lpbi; 
 
    // get the number of colors in the DIB  
 
    wNumColors = DIBNumColors(lpbi); 
 
    // is this a Win 3.0 DIB? 
 
    bWinStyleDIB = IS_WIN30_DIB(lpbi); 
    if (wNumColors) 
    { 
        // allocate memory block for logical palette 
 
        hLogPal = GlobalAlloc(GHND, sizeof(LOGPALETTE) + 
                sizeof(PALETTEENTRY) * wNumColors); 
 
        // if not enough memory, clean up and return NULL 
 
        if (!hLogPal) 
        { 
            GlobalUnlock(hDIB); 
            return NULL; 
        } 
 
        // lock memory block and get pointer to it 
 
        lpPal = (LPLOGPALETTE)GlobalLock(hLogPal); 
 
        // set version and number of palette entries 
 
        lpPal->palVersion = PALVERSION; 
        lpPal->palNumEntries = wNumColors; 
 
        // store RGB triples (if Win 3.0 DIB) or RGB quads (if OS/2 DIB) 
        // into palette 
         
        for (i = 0; i < wNumColors; i++) 
        { 
            if (bWinStyleDIB) 
            { 
                lpPal->palPalEntry[i].peRed = lpbmi->bmiColors[i].rgbRed; 
                lpPal->palPalEntry[i].peGreen = lpbmi->bmiColors[i].rgbGreen; 
                lpPal->palPalEntry[i].peBlue = lpbmi->bmiColors[i].rgbBlue; 
                lpPal->palPalEntry[i].peFlags = 0; 
            } 
            else 
            { 
                lpPal->palPalEntry[i].peRed = lpbmc->bmciColors[i].rgbtRed; 
                lpPal->palPalEntry[i].peGreen = lpbmc->bmciColors[i].rgbtGreen; 
                lpPal->palPalEntry[i].peBlue = lpbmc->bmciColors[i].rgbtBlue; 
                lpPal->palPalEntry[i].peFlags = 0; 
            } 
        } 
 
        // create the palette and get handle to it 
 
        hPal = CreatePalette(lpPal); 
 
        // if error getting handle to palette, clean up and return NULL 
 
        if (!hPal) 
        { 
            GlobalUnlock(hLogPal); 
            GlobalFree(hLogPal); 
            return NULL; 
        } 
    } 
 
    // clean up  
 
    GlobalUnlock(hLogPal); 
    GlobalFree(hLogPal); 
    GlobalUnlock(hDIB); 
 
    // return handle to DIB's palette 
    return hPal; 
} 
 
 
/************************************************************************* 
 * 
 * DIBToBitmap() 
 * 
 * Parameters: 
 * 
 * HDIB hDIB        - specifies the DIB to convert 
 * 
 * HPALETTE hPal    - specifies the palette to use with the bitmap 
 * 
 * Return Value: 
 * 
 * HBITMAP          - identifies the device-dependent bitmap 
 * 
 * Description: 
 * 
 * This function creates a bitmap from a DIB using the specified palette. 
 * If no palette is specified, default is used. 
 * 
 * NOTE: 
 * 
 * The bitmap returned from this funciton is always a bitmap compatible 
 * with the screen (e.g. same bits/pixel and color planes) rather than 
 * a bitmap with the same attributes as the DIB.  This behavior is by 
 * design, and occurs because this function calls CreateDIBitmap to 
 * do its work, and CreateDIBitmap always creates a bitmap compatible 
 * with the hDC parameter passed in (because it in turn calls 
 * CreateCompatibleBitmap). 
 * 
 * So for instance, if your DIB is a monochrome DIB and you call this 
 * function, you will not get back a monochrome HBITMAP -- you will 
 * get an HBITMAP compatible with the screen DC, but with only 2 
 * colors used in the bitmap. 
 * 
 * If your application requires a monochrome HBITMAP returned for a 
 * monochrome DIB, use the function SetDIBits(). 
 * 
 * Also, the DIBpassed in to the function is not destroyed on exit. This 
 * must be done later, once it is no longer needed. 
 * 
 ************************************************************************/ 
/* 
HBITMAP DIBToBitmap(HDIB hDIB, HPALETTE hPal) 
{ 
    LPSTR       lpDIBHdr, lpDIBBits;  // pointer to DIB header, pointer to DIB bits 
    HBITMAP     hBitmap;            // handle to device-dependent bitmap 
    HDC         hDC;                    // handle to DC 
    HPALETTE    hOldPal = NULL;    // handle to a palette 
 
    // if invalid handle, return NULL  
 
    if (!hDIB) 
        return NULL; 
 
    // lock memory block and get a pointer to it 
 
    lpDIBHdr = (char*)GlobalLock(hDIB); 
 
    // get a pointer to the DIB bits 
 
    lpDIBBits = FindDIBBits(lpDIBHdr); 
 
    // get a DC  
 
    hDC = GetDC(NULL); 
    if (!hDC) 
    { 
        // clean up and return NULL 
 
        GlobalUnlock(hDIB); 
        return NULL; 
    } 
 
    // select and realize palette 
 
    if (hPal) 
        hOldPal = SelectPalette(hDC, hPal, FALSE); 
 
    RealizePalette(hDC); 
 
    // create bitmap from DIB info. and bits 
    hBitmap = CreateDIBitmap(hDC, (LPBITMAPINFOHEADER)lpDIBHdr, CBM_INIT, 
            lpDIBBits, (LPBITMAPINFO)lpDIBHdr, DIB_RGB_COLORS); 
 
    // restore previous palette 
    if (hOldPal) 
        SelectPalette(hDC, hOldPal, FALSE); 
 
    // clean up 
    ReleaseDC(NULL, hDC); 
    GlobalUnlock(hDIB); 
 
    // return handle to the bitmap 
    return hBitmap; 
} 
 
 
/************************************************************************* 
 * 
 * BitmapToDIB() 
 * 
 * Parameters: 
 * 
 * HBITMAP hBitmap  - specifies the bitmap to convert 
 * 
 * HPALETTE hPal    - specifies the palette to use with the bitmap 
 * 
 * Return Value: 
 * 
 * HDIB             - identifies the device-dependent bitmap 
 * 
 * Description: 
 * 
 * This function creates a DIB from a bitmap using the specified palette. 
 * 
 ************************************************************************/ 

//HDIB BitmapToDIB(HBITMAP hBitmap, HPALETTE hPal);

HBITMAP CopyHDCToBitmap(HDC hDC, int width, int height);
void SaveDIB(HDIB hDib, LPSTR lpFileName);


 
/************************************************************************* 
 * 
 * PalEntriesOnDevice() 
 * 
 * Parameter: 
 * 
 * HDC hDC          - device context 
 * 
 * Return Value: 
 * 
 * int              - number of palette entries on device 
 * 
 * Description: 
 * 
 * This function gets the number of palette entries on the specified device 
 * 
 ************************************************************************/ 
/* 
int PalEntriesOnDevice(HDC hDC) 
{ 
    int nColors;  // number of colors 
 
    // Find out the number of colors on this device. 
     
    nColors = (1 << (GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES))); 
 
    assert(nColors); 
    return nColors; 
} 
 
 
/************************************************************************* 
 * 
 * GetSystemPalette() 
 * 
 * Parameters: 
 * 
 * None 
 * 
 * Return Value: 
 * 
 * HPALETTE         - handle to a copy of the current system palette 
 * 
 * Description: 
 * 
 * This function returns a handle to a palette which represents the system 
 * palette.  The system RGB values are copied into our logical palette using 
 * the GetSystemPaletteEntries function.   
 * 
 ************************************************************************/ 
/* 
HPALETTE GetSystemPalette(void) 
{ 
    HDC hDC;                // handle to a DC 
    static HPALETTE hPal = NULL;   // handle to a palette 
    HANDLE hLogPal;         // handle to a logical palette 
    LPLOGPALETTE lpLogPal;  // pointer to a logical palette 
    int nColors;            // number of colors 
 
    // Find out how many palette entries we want. 
 
    hDC = GetDC(NULL); 
 
    if (!hDC) 
        return NULL; 
 
    nColors = PalEntriesOnDevice(hDC);   // Number of palette entries 
 
    // Allocate room for the palette and lock it. 
 
    hLogPal = GlobalAlloc(GHND, sizeof(LOGPALETTE) + nColors * 
            sizeof(PALETTEENTRY)); 
 
    // if we didn't get a logical palette, return NULL 
 
    if (!hLogPal) 
        return NULL; 
 
    // get a pointer to the logical palette 
 
    lpLogPal = (LPLOGPALETTE)GlobalLock(hLogPal); 
 
    // set some important fields 
 
    lpLogPal->palVersion = PALVERSION; 
    lpLogPal->palNumEntries = nColors; 
 
    // Copy the current system palette into our logical palette 
 
    GetSystemPaletteEntries(hDC, 0, nColors, 
            (LPPALETTEENTRY)(lpLogPal->palPalEntry)); 
 
    // Go ahead and create the palette.  Once it's created, 
    // we no longer need the LOGPALETTE, so free it.     
 
    hPal = CreatePalette(lpLogPal); 
 
    // clean up 
 
    GlobalUnlock(hLogPal); 
    GlobalFree(hLogPal); 
    ReleaseDC(NULL, hDC); 
 
    return hPal; 
} 
 
 
/************************************************************************* 
 * 
 * AllocRoomForDIB() 
 * 
 * Parameters: 
 * 
 * BITMAPINFOHEADER - bitmap info header stucture 
 * 
 * HBITMAP          - handle to the bitmap 
 * 
 * Return Value: 
 * 
 * HDIB             - handle to memory block 
 * 
 * Description: 
 * 
 *  This routine takes a BITMAPINOHEADER, and returns a handle to global 
 *  memory which can contain a DIB with that header.  It also initializes 
 *  the header portion of the global memory.  GetDIBits() is used to determine 
 *  the amount of room for the DIB's bits.  The total amount of memory 
 *  needed = sizeof(BITMAPINFOHEADER) + size of color table + size of bits. 
 * 
 ************************************************************************/ 
/* 
HANDLE AllocRoomForDIB(BITMAPINFOHEADER bi, HBITMAP hBitmap) 
{ 
    DWORD               dwLen; 
    HANDLE              hDIB; 
    HDC                 hDC; 
    LPBITMAPINFOHEADER  lpbi; 
    HANDLE              hTemp; 
 
    // Figure out the size needed to hold the BITMAPINFO structure 
    // (which includes the BITMAPINFOHEADER and the color table). 
 
    dwLen = bi.biSize + PaletteSize((LPSTR) &bi); 
    hDIB  = GlobalAlloc(GHND,dwLen); 
 
    // Check that DIB handle is valid 
 
    if (!hDIB) 
        return NULL; 
 
    // Set up the BITMAPINFOHEADER in the newly allocated global memory, 
    // then call GetDIBits() with lpBits = NULL to have it fill in the 
    // biSizeImage field for us. 
 
    lpbi  = (LPBITMAPINFOHEADER)GlobalLock(hDIB); 
    *lpbi = bi; 
 
    hDC   = GetDC(NULL); 
 
    GetDIBits(hDC, hBitmap, 0, (UINT) bi.biHeight, NULL, (LPBITMAPINFO)lpbi, 
            DIB_RGB_COLORS); 
    ReleaseDC(NULL, hDC); 
 
    // If the driver did not fill in the biSizeImage field, 
    // fill it in -- NOTE: this is a bug in the driver! 
     
    if (lpbi->biSizeImage == 0) 
        lpbi->biSizeImage = WIDTHBYTES((DWORD)lpbi->biWidth * 
                lpbi->biBitCount) * lpbi->biHeight; 
 
    // Get the size of the memory block we need 
 
    dwLen = lpbi->biSize + PaletteSize((LPSTR) &bi) + lpbi->biSizeImage; 
 
    // Unlock the memory block 
 
    GlobalUnlock(hDIB); 
 
    // ReAlloc the buffer big enough to hold all the bits  
 
    if (hTemp = GlobalReAlloc(hDIB,dwLen,0)) 
        return hTemp; 
    else 
    { 
        // Else free memory block and return failure 
 
        GlobalFree(hDIB); 
        return NULL; 
    } 
} 
 
 
/************************************************************************* 
 * 
 * ChangeDIBFormat() 
 * 
 * Parameter: 
 * 
 * HDIB             - handle to packed-DIB in memory 
 * 
 * WORD             - desired bits per pixel 
 * 
 * DWORD            - desired compression format 
 * 
 * Return Value: 
 * 
 * HDIB             - handle to the new DIB if successful, else NULL 
 * 
 * Description: 
 * 
 * This function will convert the bits per pixel and/or the compression 
 * format of the specified DIB. Note: If the conversion was unsuccessful, 
 * we return NULL. The original DIB is left alone. Don't use code like the 
 * following: 
 * 
 *    hMyDIB = ChangeDIBFormat(hMyDIB, 8, BI_RLE4); 
 * 
 * The conversion will fail, but hMyDIB will now be NULL and the original 
 * DIB will now hang around in memory. We could have returned the old 
 * DIB, but we wanted to allow the programmer to check whether this 
 * conversion succeeded or failed. 
 * 
 ************************************************************************/ 
/* 
HDIB ChangeDIBFormat(HDIB hDIB, WORD wBitCount, DWORD dwCompression) 
{ 
    HDC                hDC;             // Handle to DC 
    HBITMAP            hBitmap;         // Handle to bitmap 
    BITMAP             Bitmap;          // BITMAP data structure 
    BITMAPINFOHEADER   bi;              // Bitmap info header 
    LPBITMAPINFOHEADER lpbi;            // Pointer to bitmap info 
    HDIB               hNewDIB = NULL;  // Handle to new DIB 
    HPALETTE           hPal, hOldPal;   // Handle to palette, prev pal 
    WORD               DIBBPP, NewBPP;  // DIB bits per pixel, new bpp 
    DWORD              DIBComp, NewComp;// DIB compression, new compression 
 
    // Check for a valid DIB handle 
 
    if (!hDIB) 
        return NULL; 
 
    // Get the old DIB's bits per pixel and compression format 
 
    lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB); 
    DIBBPP = ((LPBITMAPINFOHEADER)lpbi)->biBitCount; 
    DIBComp = ((LPBITMAPINFOHEADER)lpbi)->biCompression; 
    GlobalUnlock(hDIB); 
 
    // Validate wBitCount and dwCompression 
    // They must match correctly (i.e., BI_RLE4 and 4 BPP or 
    // BI_RLE8 and 8BPP, etc.) or we return failure 
    if (wBitCount == 0) 
    { 
        NewBPP = DIBBPP; 
        if ((dwCompression == BI_RLE4 && NewBPP == 4) || 
                (dwCompression == BI_RLE8 && NewBPP == 8) || 
                (dwCompression == BI_RGB)) 
            NewComp = dwCompression; 
        else 
            return NULL; 
    } 
    else if (wBitCount == 1 && dwCompression == BI_RGB) 
    { 
        NewBPP = wBitCount; 
NewComp = BI_RGB; 
    } 
    else if (wBitCount == 4) 
    { 
        NewBPP = wBitCount; 
        if (dwCompression == BI_RGB || dwCompression == BI_RLE4) 
            NewComp = dwCompression; 
        else 
            return NULL; 
    } 
    else if (wBitCount == 8) 
    { 
        NewBPP = wBitCount; 
        if (dwCompression == BI_RGB || dwCompression == BI_RLE8) 
            NewComp = dwCompression; 
        else 
            return NULL; 
    } 
    else if (wBitCount == 24 && dwCompression == BI_RGB) 
    { 
        NewBPP = wBitCount; 
        NewComp = BI_RGB; 
    } 
    else 
        return NULL; 
 
    // Save the old DIB's palette 
 
    hPal = CreateDIBPalette(hDIB); 
    if (!hPal) 
        return NULL; 
 
    // Convert old DIB to a bitmap 
 
    hBitmap = DIBToBitmap(hDIB, hPal); 
    if (!hBitmap) 
    { 
        DeleteObject(hPal); 
        return NULL; 
    } 
 
    // Get info about the bitmap 
    GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap); 
 
    // Fill in the BITMAPINFOHEADER appropriately 
 
    bi.biSize               = sizeof(BITMAPINFOHEADER); 
    bi.biWidth              = Bitmap.bmWidth; 
    bi.biHeight             = Bitmap.bmHeight; 
    bi.biPlanes             = 1; 
    bi.biBitCount           = NewBPP; 
    bi.biCompression        = NewComp; 
    bi.biSizeImage          = 0; 
    bi.biXPelsPerMeter      = 0; 
    bi.biYPelsPerMeter      = 0; 
    bi.biClrUsed            = 0; 
    bi.biClrImportant       = 0; 
 
    // Go allocate room for the new DIB 
 
    hNewDIB = AllocRoomForDIB(bi, hBitmap); 
    if (!hNewDIB) 
        return NULL; 
 
    // Get a pointer to the new DIB 
 
    lpbi = (LPBITMAPINFOHEADER)GlobalLock(hNewDIB); 
 
    // Get a DC and select/realize our palette in it 
 
    hDC  = GetDC(NULL); 
    hOldPal = SelectPalette(hDC, hPal, FALSE); 
    RealizePalette(hDC); 
 
    // Call GetDIBits and get the new DIB bits 
 
    if (!GetDIBits(hDC, hBitmap, 0, (UINT) lpbi->biHeight, 
            (LPSTR)lpbi + (WORD)lpbi->biSize + PaletteSize((LPSTR)lpbi), 
            (LPBITMAPINFO)lpbi, DIB_RGB_COLORS)) 
    { 
        GlobalUnlock(hNewDIB); 
        GlobalFree(hNewDIB); 
        hNewDIB = NULL; 
    } 
 
    // Clean up and return 
 
    SelectPalette(hDC, hOldPal, TRUE); 
    RealizePalette(hDC); 
    ReleaseDC(NULL, hDC); 
 
    // Unlock the new DIB's memory block 
    if (hNewDIB) 
        GlobalUnlock(hNewDIB); 
 
    DeleteObject(hBitmap); 
    DeleteObject(hPal); 
 
    return hNewDIB; 
} 
 
 
/************************************************************************* 
 * 
 * ChangeBitmapFormat() 
 * 
 * Parameter: 
 * 
 * HBITMAP          - handle to a bitmap 
 * 
 * WORD             - desired bits per pixel 
 * 
 * DWORD            - desired compression format 
 * 
 * HPALETTE         - handle to palette 
 * 
 * Return Value: 
 * 
 * HDIB             - handle to the new DIB if successful, else NULL 
 * 
 * Description: 
 * 
 * This function will convert a bitmap to the specified bits per pixel 
 * and compression format. The bitmap and it's palette will remain 
 * after calling this function. 
 * 
 ************************************************************************/ 
/* 
HDIB ChangeBitmapFormat(HBITMAP hBitmap, WORD wBitCount, DWORD dwCompression, 
        HPALETTE hPal) 
{ 
    HDC                hDC;          // Screen DC 
    HDIB               hNewDIB=NULL; // Handle to new DIB 
    BITMAP             Bitmap;       // BITMAP data structure 
    BITMAPINFOHEADER   bi;           // Bitmap info. header 
    LPBITMAPINFOHEADER lpbi;         // Pointer to bitmap header 
    HPALETTE           hOldPal=NULL; // Handle to palette 
    WORD               NewBPP;       // New bits per pixel 
    DWORD              NewComp;      // New compression format 
 
    // Check for a valid bitmap handle 
 
    if (!hBitmap) 
        return NULL; 
 
    // Validate wBitCount and dwCompression 
    // They must match correctly (i.e., BI_RLE4 and 4 BPP or 
    // BI_RLE8 and 8BPP, etc.) or we return failure 
     
    if (wBitCount == 0) 
    { 
        NewComp = dwCompression; 
        if (NewComp == BI_RLE4) 
            NewBPP = 4; 
        else if (NewComp == BI_RLE8) 
            NewBPP = 8; 
        else // Not enough info  
            return NULL; 
    } 
    else if (wBitCount == 1 && dwCompression == BI_RGB) 
    { 
        NewBPP = wBitCount; 
        NewComp = BI_RGB; 
    } 
    else if (wBitCount == 4) 
    { 
        NewBPP = wBitCount; 
        if (dwCompression == BI_RGB || dwCompression == BI_RLE4) 
            NewComp = dwCompression; 
        else 
            return NULL; 
    } 
    else if (wBitCount == 8) 
    { 
        NewBPP = wBitCount; 
        if (dwCompression == BI_RGB || dwCompression == BI_RLE8) 
            NewComp = dwCompression; 
        else 
            return NULL; 
    } 
    else if (wBitCount == 24 && dwCompression == BI_RGB) 
    { 
        NewBPP = wBitCount; 
        NewComp = BI_RGB; 
    } 
    else 
        return NULL; 
 
    // Get info about the bitmap 
 
    GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap); 
 
    // Fill in the BITMAPINFOHEADER appropriately 
 
    bi.biSize               = sizeof(BITMAPINFOHEADER); 
    bi.biWidth              = Bitmap.bmWidth; 
    bi.biHeight             = Bitmap.bmHeight; 
    bi.biPlanes             = 1; 
    bi.biBitCount           = NewBPP; 
    bi.biCompression        = NewComp; 
    bi.biSizeImage          = 0; 
    bi.biXPelsPerMeter      = 0; 
    bi.biYPelsPerMeter      = 0; 
    bi.biClrUsed            = 0; 
    bi.biClrImportant       = 0; 
 
    // Go allocate room for the new DIB 
 
    hNewDIB = AllocRoomForDIB(bi, hBitmap); 
    if (!hNewDIB) 
        return NULL; 
 
    // Get a pointer to the new DIB 
 
    lpbi = (LPBITMAPINFOHEADER)GlobalLock(hNewDIB); 
 
    // If we have a palette, get a DC and select/realize it 
 
    if (hPal) 
    { 
        hDC  = GetDC(NULL); 
        hOldPal = SelectPalette(hDC, hPal, FALSE); 
        RealizePalette(hDC); 
    } 
 
    // Call GetDIBits and get the new DIB bits 
 
    if (!GetDIBits(hDC, hBitmap, 0, (UINT) lpbi->biHeight, (LPSTR)lpbi + 
            (WORD)lpbi->biSize + PaletteSize((LPSTR)lpbi), (LPBITMAPINFO)lpbi, 
            DIB_RGB_COLORS)) 
    { 
        GlobalUnlock(hNewDIB); 
        GlobalFree(hNewDIB); 
        hNewDIB = NULL; 
    } 
 
    // Clean up and return 
 
    if (hOldPal) 
    { 
        SelectPalette(hDC, hOldPal, TRUE); 
        RealizePalette(hDC); 
        ReleaseDC(NULL, hDC); 
    } 
 
    // Unlock the new DIB's memory block 
 
    if (hNewDIB) 
        GlobalUnlock(hNewDIB); 
 
    return hNewDIB; 
} */
;int getA()
{
	return 0;
}

