| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260 | 
							- //**********************************************************************
 
- //
 
- //  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 = (LPSTR)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 = (LPSTR)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)
 
- {
 
-     BITMAP              bm;         // bitmap structure
 
-     BITMAPINFOHEADER    bi;         // bitmap header
 
-     LPBITMAPINFOHEADER  lpbi;       // pointer to BITMAPINFOHEADER
 
-     DWORD               dwLen;      // size of memory block
 
-     HANDLE              hDIB, h;    // handle to DIB, temp handle
 
-     HDC                 hDC;        // handle to DC
 
-     WORD                biBits;     // bits per pixel
 
-     // check if bitmap handle is valid
 
-     if (!hBitmap)
 
-         return NULL;
 
-     // fill in BITMAP structure, return NULL if it didn't work
 
-     if (!GetObject(hBitmap, sizeof(bm), (LPSTR)&bm))
 
-         return NULL;
 
-     // if no palette is specified, use default palette
 
-     if (hPal == NULL)
 
-         hPal = (HPALETTE)GetStockObject(DEFAULT_PALETTE);
 
-     // calculate bits per pixel
 
-     biBits = bm.bmPlanes * bm.bmBitsPixel;
 
-     // make sure bits per pixel is valid
 
-     if (biBits <= 1)
 
-         biBits = 1;
 
-     else if (biBits <= 4)
 
-         biBits = 4;
 
-     else if (biBits <= 8)
 
-         biBits = 8;
 
-     else if (biBits <= 24)
 
-         biBits = 24;
 
- 	else
 
- 		biBits = 32;
 
-     // initialize BITMAPINFOHEADER
 
-     bi.biSize = sizeof(BITMAPINFOHEADER);
 
-     bi.biWidth = bm.bmWidth;
 
-     bi.biHeight = bm.bmHeight;
 
-     bi.biPlanes = 1;
 
-     bi.biBitCount = biBits;
 
-     bi.biCompression = BI_RGB;
 
-     bi.biSizeImage = 0;
 
-     bi.biXPelsPerMeter = 0;
 
-     bi.biYPelsPerMeter = 0;
 
-     bi.biClrUsed = 0;
 
-     bi.biClrImportant = 0;
 
-     // calculate size of memory block required to store BITMAPINFO
 
-     dwLen = bi.biSize + PaletteSize((LPSTR)&bi);
 
-     // get a DC
 
-     hDC = GetDC(NULL);
 
-     // select and realize our palette
 
-     hPal = SelectPalette(hDC, hPal, FALSE);
 
-     RealizePalette(hDC);
 
-     // alloc memory block to store our bitmap
 
-     hDIB = GlobalAlloc(GHND, dwLen);
 
-     // if we couldn't get memory block
 
-     if (!hDIB)
 
-     {
 
-       // clean up and return NULL
 
-       SelectPalette(hDC, hPal, TRUE);
 
-       RealizePalette(hDC);
 
-       ReleaseDC(NULL, hDC);
 
-       return NULL;
 
-     }
 
-     // lock memory and get pointer to it
 
-     lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
 
-     /// use our bitmap info. to fill BITMAPINFOHEADER
 
-     *lpbi = bi;
 
-     // call GetDIBits with a NULL lpBits param, so it will calculate the
 
-     // biSizeImage field for us    
 
-     GetDIBits(hDC, hBitmap, 0, (UINT)bi.biHeight, NULL, (LPBITMAPINFO)lpbi,
 
-         DIB_RGB_COLORS);
 
-     // get the info. returned by GetDIBits and unlock memory block
 
-     bi = *lpbi;
 
-     GlobalUnlock(hDIB);
 
-     // if the driver did not fill in the biSizeImage field, make one up 
 
-     if (bi.biSizeImage == 0)
 
-         bi.biSizeImage = WIDTHBYTES((DWORD)bm.bmWidth * biBits) * bm.bmHeight;
 
-     // realloc the buffer big enough to hold all the bits
 
-     dwLen = bi.biSize + PaletteSize((LPSTR)&bi) + bi.biSizeImage;
 
-     if (h = GlobalReAlloc(hDIB, dwLen, 0))
 
-         hDIB = h;
 
-     else
 
-     {
 
-         // clean up and return NULL
 
-         GlobalFree(hDIB);
 
-         hDIB = NULL;
 
-         SelectPalette(hDC, hPal, TRUE);
 
-         RealizePalette(hDC);
 
-         ReleaseDC(NULL, hDC);
 
-         return NULL;
 
-     }
 
-     // lock memory block and get pointer to it */
 
-     lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
 
-     // call GetDIBits with a NON-NULL lpBits param, and actualy get the
 
-     // bits this time
 
-     if (GetDIBits(hDC, hBitmap, 0, (UINT)bi.biHeight, (LPSTR)lpbi +
 
-             (WORD)lpbi->biSize + PaletteSize((LPSTR)lpbi), (LPBITMAPINFO)lpbi,
 
-             DIB_RGB_COLORS) == 0)
 
-     {
 
-         // clean up and return NULL
 
-         GlobalUnlock(hDIB);
 
-         hDIB = NULL;
 
-         SelectPalette(hDC, hPal, TRUE);
 
-         RealizePalette(hDC);
 
-         ReleaseDC(NULL, hDC);
 
-         return NULL;
 
-     }
 
-     bi = *lpbi;
 
-     // clean up 
 
-     GlobalUnlock(hDIB);
 
-     SelectPalette(hDC, hPal, TRUE);
 
-     RealizePalette(hDC);
 
-     ReleaseDC(NULL, hDC);
 
-     // return handle to the DIB
 
-     return hDIB;
 
- }
 
- /*************************************************************************
 
-  *
 
-  * 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;
 
- }
 
 
  |