DIB.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:37k
源码类别:

Windows编程

开发平台:

Visual C++

  1. /******************************************************************************
  2. *       This is a part of the Microsoft Source Code Samples. 
  3. *       Copyright (C) 1993-1997 Microsoft Corporation.
  4. *       All rights reserved. 
  5. *       This source code is only intended as a supplement to 
  6. *       Microsoft Development Tools and/or WinHelp documentation.
  7. *       See these sources for detailed information regarding the 
  8. *       Microsoft samples programs.
  9. ******************************************************************************/
  10. /*******************************************************************************
  11.  *                                                                             *
  12.  *  MODULE      : DIB.C                                                        *
  13.  *                                                                             *
  14.  *  DESCRIPTION : Routines for dealing with Device Independent Bitmaps.        *
  15.  *                                                                             *
  16.  *  FUNCTIONS   : OpenDIB()           - Opens DIB file and creates a memory DIB*
  17.  *                                                                             *
  18.  *                WriteDIB()          - Writes a global handle in CF_DIB format*
  19.  *                                      to a file.                             *
  20.  *                                                                             *
  21.  *                DibInfo()           - Retrieves the info. block associated   *
  22.  *                                      with a CF_DIB format memory block.     *
  23.  *                                                                             *
  24.  *                CreateBIPalette()   - Creates a GDI palette given a pointer  *
  25.  *                                      to a BITMAPINFO structure.             *
  26.  *                                                                             *
  27.  *                CreateDibPalette()  - Creates a GDI palette given a HANDLE   *
  28.  *                                      to a BITMAPINFO structure.             *
  29.  *                                                                             *
  30.  *                ReadDibBitmapInfo() - Reads a file in DIB format and returns *
  31.  *                                      a global handle to it's BITMAPINFO     *
  32.  *                                                                             *
  33.  *                PaletteSize()       - Calculates the palette size in bytes   *
  34.  *                                      of given DIB                           *
  35.  *                                                                             *
  36.  *                DibNumColors()      - Determines the number of colors in DIB *
  37.  *                                                                             *
  38.  *                BitmapFromDib()     - Creates a DDB given a global handle to *
  39.  *                                      a block in CF_DIB format.              *
  40.  *                                                                             *
  41.  *                DibFromBitmap()     - Creates a DIB repr. the DDB passed in. *
  42.  *                                                                             *
  43.  *                DrawBitmap()        - Draws a bitmap at specified position   *
  44.  *                                      in the DC.                             *
  45.  *                                                                             *
  46.  *                DibBlt()            - Draws a bitmap in CIF_DIB format using *
  47.  *                                      SetDIBitsToDevice()                    *
  48.  *                                                                             *
  49.  *                StretchDibBlt()     - Draws a bitmap in CIF_DIB format using *
  50.  *                                      StretchDIBits()                        *
  51.  *                                                                             *
  52.  *                lread()             - Private routine to read more than 64k  *
  53.  *                                                                             *
  54.  *                lwrite()            - Private routine to write more than 64k *
  55.  *                                                                             *
  56.  *******************************************************************************/
  57. #include <windows.h>
  58. #include "showdib.h"
  59. static   HCURSOR hcurSave;
  60. /****************************************************************************
  61.  *                                                                          *
  62.  *  FUNCTION   :OpenDIB(LPSTR szFile)                                       *
  63.  *                                                                          *
  64.  *  PURPOSE    :Open a DIB file and create a MEMORY DIB, a memory handle    *
  65.  *              containing BITMAPINFO, palette data and the bits.           *
  66.  *                                                                          *
  67.  *  RETURNS    :A handle to the DIB.                                        *
  68.  *                                                                          *
  69.  ****************************************************************************/
  70. HANDLE OpenDIB (LPSTR szFile)
  71. {
  72.     HFILE               fh;
  73.     BITMAPINFOHEADER    bi;
  74.     LPBITMAPINFOHEADER  lpbi;
  75.     DWORD               dwLen = 0;
  76.     DWORD               dwBits;
  77.     HANDLE              hdib;
  78.     HANDLE              h;
  79.     OFSTRUCT            of;
  80.     /* Open the file and read the DIB information */
  81.     fh = OpenFile(szFile, &of, (UINT)OF_READ);
  82.     if (fh == -1)
  83.         return NULL;
  84.     hdib = ReadDibBitmapInfo(fh);
  85.     if (!hdib)
  86.         return NULL;
  87.     DibInfo(hdib,&bi);
  88.     /* Calculate the memory needed to hold the DIB */
  89.     dwBits = bi.biSizeImage;
  90.     dwLen  = bi.biSize + (DWORD)PaletteSize (&bi) + dwBits;
  91.     /* Try to increase the size of the bitmap info. buffer to hold the DIB */
  92.     h = GlobalReAlloc(hdib, dwLen, GHND);
  93.     if (!h){
  94.         GlobalFree(hdib);
  95.         hdib = NULL;
  96.     }
  97.     else
  98.         hdib = h;
  99.     /* Read in the bits */
  100.     if (hdib){
  101.         lpbi = (VOID FAR *)GlobalLock(hdib);
  102.         lread(fh, (LPSTR)lpbi + (WORD)lpbi->biSize + PaletteSize(lpbi), dwBits);
  103.         GlobalUnlock(hdib);
  104.     }
  105.     _lclose(fh);
  106.     return hdib;
  107. }
  108. /****************************************************************************
  109.  *                                                                          *
  110.  *  FUNCTION   : WriteDIB(LPSTR szFile,HANDLE hdib)                         *
  111.  *                                                                          *
  112.  *  PURPOSE    : Write a global handle in CF_DIB format to a file.          *
  113.  *                                                                          *
  114.  *  RETURNS    : TRUE  - if successful.                                     *
  115.  *               FALSE - otherwise                                          *
  116.  *                                                                          *
  117.  ****************************************************************************/
  118. BOOL WriteDIB (
  119.     LPSTR szFile,
  120.     HANDLE hdib)
  121. {
  122.     BITMAPFILEHEADER    hdr;
  123.     LPBITMAPINFOHEADER  lpbi;
  124.     HFILE               fh;
  125.     OFSTRUCT            of;
  126.     if (!hdib)
  127.         return FALSE;
  128.     fh = OpenFile(szFile, &of, (UINT)OF_CREATE|OF_READWRITE);
  129.     if (fh == -1)
  130.         return FALSE;
  131.     lpbi = (VOID FAR *)GlobalLock (hdib);
  132.     /* Fill in the fields of the file header */
  133.     hdr.bfType          = BFT_BITMAP;
  134.     hdr.bfSize          = GlobalSize (hdib) + SIZEOF_BITMAPFILEHEADER_PACKED;
  135.     hdr.bfReserved1     = 0;
  136.     hdr.bfReserved2     = 0;
  137.     hdr.bfOffBits       = (DWORD) (SIZEOF_BITMAPFILEHEADER_PACKED + lpbi->biSize +
  138.                           PaletteSize(lpbi));
  139.     /* Write the file header */
  140. #ifdef  FIXDWORDALIGNMENT
  141.     _lwrite(fh, (LPSTR)&hdr, (UINT)(SIZEOF_BITMAPFILEHEADER_PACKED));
  142. #else
  143.         WriteMapFileHeaderandConvertFromDwordAlignToPacked(fh, &hdr);
  144. #endif
  145.         /* this struct already DWORD aligned!*/
  146.     /* Write the DIB header and the bits */
  147.     lwrite (fh, (LPSTR)lpbi, GlobalSize (hdib));
  148.     GlobalUnlock (hdib);
  149.     _lclose(fh);
  150.     return TRUE;
  151. }
  152. /****************************************************************************
  153.  *                                                                          *
  154.  *  FUNCTION   : DibInfo(HANDLE hbi,LPBITMAPINFOHEADER lpbi)                *
  155.  *                                                                          *
  156.  *  PURPOSE    : Retrieves the DIB info associated with a CF_DIB            *
  157.  *               format memory block.                                       *
  158.  *                                                                          *
  159.  *  RETURNS    : TRUE  - if successful.                                     *
  160.  *               FALSE - otherwise                                          *
  161.  *                                                                          *
  162.  ****************************************************************************/
  163. BOOL DibInfo (
  164.     HANDLE hbi,
  165.     LPBITMAPINFOHEADER lpbi)
  166. {
  167.     if (hbi){
  168.         *lpbi = *(LPBITMAPINFOHEADER)GlobalLock (hbi);
  169.         /* fill in the default fields */
  170.         if (lpbi->biSize != sizeof (BITMAPCOREHEADER)){
  171.             if (lpbi->biSizeImage == 0L)
  172.                                 lpbi->biSizeImage = WIDTHBYTES(lpbi->biWidth*lpbi->biBitCount) * lpbi->biHeight;
  173.             if (lpbi->biClrUsed == 0L)
  174.                                 lpbi->biClrUsed = DibNumColors (lpbi);
  175.     }
  176.         GlobalUnlock (hbi);
  177.         return TRUE;
  178.     }
  179.     return FALSE;
  180. }
  181. /****************************************************************************
  182.  *                                                                          *
  183.  *  FUNCTION   : CreateBIPalette(LPBITMAPINFOHEADER lpbi)                   *
  184.  *                                                                          *
  185.  *  PURPOSE    : Given a Pointer to a BITMAPINFO struct will create a       *
  186.  *               a GDI palette object from the color table.                 *
  187.  *                                                                          *
  188.  *  RETURNS    : A handle to the palette.                                   *
  189.  *                                                                          *
  190.  ****************************************************************************/
  191. HPALETTE CreateBIPalette (LPBITMAPINFOHEADER lpbi)
  192. {
  193.     LOGPALETTE          *pPal;
  194.     HPALETTE            hpal = NULL;
  195.     WORD                nNumColors;
  196.     BYTE                red;
  197.     BYTE                green;
  198.     BYTE                blue;
  199.     WORD                i;
  200.     RGBQUAD        FAR *pRgb;
  201.     if (!lpbi)
  202.         return NULL;
  203.     if (lpbi->biSize != sizeof(BITMAPINFOHEADER))
  204.         return NULL;
  205.     /* Get a pointer to the color table and the number of colors in it */
  206.     pRgb = (RGBQUAD FAR *)((LPSTR)lpbi + (WORD)lpbi->biSize);
  207.     nNumColors = DibNumColors(lpbi);
  208.     if (nNumColors){
  209.         /* Allocate for the logical palette structure */
  210.         pPal = (LOGPALETTE*)LocalAlloc(LPTR,sizeof(LOGPALETTE) + nNumColors * sizeof(PALETTEENTRY));
  211.         if (!pPal)
  212.             return NULL;
  213.         pPal->palNumEntries = nNumColors;
  214.         pPal->palVersion    = PALVERSION;
  215.         /* Fill in the palette entries from the DIB color table and
  216.          * create a logical color palette.
  217.          */
  218.         for (i = 0; i < nNumColors; i++){
  219.             pPal->palPalEntry[i].peRed   = pRgb[i].rgbRed;
  220.             pPal->palPalEntry[i].peGreen = pRgb[i].rgbGreen;
  221.             pPal->palPalEntry[i].peBlue  = pRgb[i].rgbBlue;
  222.             pPal->palPalEntry[i].peFlags = (BYTE)0;
  223.         }
  224.         hpal = CreatePalette(pPal);
  225.         LocalFree((HANDLE)pPal);
  226.     }
  227.     else if (lpbi->biBitCount == 24){
  228.         /* A 24 bitcount DIB has no color table entries so, set the number of
  229.          * to the maximum value (256).
  230.          */
  231.         nNumColors = MAXPALETTE;
  232.         pPal = (LOGPALETTE*)LocalAlloc(LPTR,sizeof(LOGPALETTE) + nNumColors * sizeof(PALETTEENTRY));
  233.         if (!pPal)
  234.             return NULL;
  235.         pPal->palNumEntries = nNumColors;
  236.         pPal->palVersion    = PALVERSION;
  237.         red = green = blue = 0;
  238.         /* Generate 256 (= 8*8*4) RGB combinations to fill the palette
  239.          * entries.
  240.          */
  241.         for (i = 0; i < pPal->palNumEntries; i++){
  242.             pPal->palPalEntry[i].peRed   = red;
  243.             pPal->palPalEntry[i].peGreen = green;
  244.             pPal->palPalEntry[i].peBlue  = blue;
  245.             pPal->palPalEntry[i].peFlags = (BYTE)0;
  246.             if (!(red += 32))
  247.                 if (!(green += 32))
  248.                     blue += 64;
  249.         }
  250.         hpal = CreatePalette(pPal);
  251.         LocalFree((HANDLE)pPal);
  252.     }
  253.     return hpal;
  254. }
  255. /****************************************************************************
  256.  *                                                                          *
  257.  *  FUNCTION   : CreateDibPalette(HANDLE hbi)                               *
  258.  *                                                                          *
  259.  *  PURPOSE    : Given a Global HANDLE to a BITMAPINFO Struct               *
  260.  *               will create a GDI palette object from the color table.     *
  261.  *               (BITMAPINFOHEADER format DIBs only)                                     *
  262.  *                                                                          *
  263.  *  RETURNS    : A handle to the palette.                                   *
  264.  *                                                                          *
  265.  ****************************************************************************/
  266. HPALETTE CreateDibPalette (HANDLE hbi)
  267. {
  268.     HPALETTE hpal;
  269.     if (!hbi)
  270.         return NULL;
  271.     hpal = CreateBIPalette((LPBITMAPINFOHEADER)GlobalLock(hbi));
  272.     GlobalUnlock(hbi);
  273.     return hpal;
  274. }
  275. /****************************************************************************
  276.  *                                                                          *
  277.  *  FUNCTION   : ReadDibBitmapInfo(int fh)                                  *
  278.  *                                                                          *
  279.  *  PURPOSE    : Will read a file in DIB format and return a global HANDLE  *
  280.  *               to it's BITMAPINFO.  This function will work with both     *
  281.  *               "old" (BITMAPCOREHEADER) and "new" (BITMAPINFOHEADER)      *
  282.  *               bitmap formats, but will always return a "new" BITMAPINFO  *
  283.  *                                                                          *
  284.  *  RETURNS    : A handle to the BITMAPINFO of the DIB in the file.         *
  285.  *                                                                          *
  286.  ****************************************************************************/
  287. HANDLE ReadDibBitmapInfo (INT fh)
  288. {
  289.     DWORD     off;
  290.     HANDLE    hbi = NULL;
  291.     INT       size;
  292.     INT       i;
  293.     WORD      nNumColors;
  294.     RGBQUAD FAR       *pRgb;
  295.     BITMAPINFOHEADER   bi;
  296.     BITMAPCOREHEADER   bc;
  297.     LPBITMAPINFOHEADER lpbi;
  298.     BITMAPFILEHEADER   bf;
  299.     DWORD              dwWidth = 0;
  300.     DWORD              dwHeight = 0;
  301.     WORD               wPlanes, wBitCount;
  302.     if (fh == -1)
  303.         return NULL;
  304. #ifdef FIXDWORDALIGNMENT
  305.     /* Reset file pointer and read file header */
  306.     off = _llseek(fh, 0L, (UINT)SEEK_CUR);
  307.     if ((SIZEOF_BITMAPFILEHEADER_PACKED)  != _lread(fh, (LPSTR)&bf, (UINT)sizeof (SIZEOF_BITMAPFILEHEADER_PACKED)))
  308.         return FALSE;
  309. #else
  310.         ReadBitMapFileHeaderandConvertToDwordAlign(fh, &bf, &off);
  311.         /* at this point we have read the file into bf*/
  312. #endif
  313.     /* Do we have a RC HEADER? */
  314.     if (!ISDIB (bf.bfType)) {    
  315.         bf.bfOffBits = 0L;               
  316.                 _llseek(fh, off, (UINT)SEEK_SET); /*seek back to beginning of file*/
  317.     }
  318.     if (sizeof (bi) != _lread(fh, (LPSTR)&bi, (UINT)sizeof(bi)))
  319.         return FALSE;
  320.     nNumColors = DibNumColors (&bi);
  321.     /* Check the nature (BITMAPINFO or BITMAPCORE) of the info. block
  322.      * and extract the field information accordingly. If a BITMAPCOREHEADER,
  323.      * transfer it's field information to a BITMAPINFOHEADER-style block
  324.      */
  325.     switch (size = (INT)bi.biSize){
  326.         case sizeof (BITMAPINFOHEADER):
  327.             break;
  328.         case sizeof (BITMAPCOREHEADER):
  329.             bc = *(BITMAPCOREHEADER*)&bi;
  330.             dwWidth   = (DWORD)bc.bcWidth;
  331.             dwHeight  = (DWORD)bc.bcHeight;
  332.             wPlanes   = bc.bcPlanes;
  333.             wBitCount = bc.bcBitCount;
  334.         bi.biSize           = sizeof(BITMAPINFOHEADER);
  335.             bi.biWidth              = dwWidth;
  336.             bi.biHeight             = dwHeight;
  337.             bi.biPlanes             = wPlanes;
  338.             bi.biBitCount           = wBitCount;
  339.             bi.biCompression        = BI_RGB;
  340.             bi.biSizeImage          = 0;
  341.             bi.biXPelsPerMeter      = 0;
  342.             bi.biYPelsPerMeter      = 0;
  343.             bi.biClrUsed            = nNumColors;
  344.             bi.biClrImportant       = nNumColors;
  345.             _llseek(fh, (LONG)sizeof (BITMAPCOREHEADER) - sizeof (BITMAPINFOHEADER), (UINT)SEEK_CUR);
  346.             break;
  347.         default:
  348.             /* Not a DIB! */
  349.             return NULL;
  350.     }
  351.     /*  Fill in some default values if they are zero */
  352.     if (bi.biSizeImage == 0){
  353.         bi.biSizeImage = WIDTHBYTES ((DWORD)bi.biWidth * bi.biBitCount)
  354.                          * bi.biHeight;
  355.     }
  356.     if (bi.biClrUsed == 0)
  357.         bi.biClrUsed = DibNumColors(&bi);
  358.     /* Allocate for the BITMAPINFO structure and the color table. */
  359.     hbi = GlobalAlloc (GHND, (LONG)bi.biSize + nNumColors * sizeof(RGBQUAD));
  360.     if (!hbi)
  361.         return NULL;
  362.     lpbi = (VOID FAR *)GlobalLock (hbi);
  363.     *lpbi = bi;
  364.     /* Get a pointer to the color table */
  365.     pRgb = (RGBQUAD FAR *)((LPSTR)lpbi + bi.biSize);
  366.     if (nNumColors){
  367.         if (size == sizeof(BITMAPCOREHEADER)){
  368.             /* Convert a old color table (3 byte RGBTRIPLEs) to a new
  369.              * color table (4 byte RGBQUADs)
  370.              */
  371.             _lread(fh, (LPSTR)pRgb, (UINT)nNumColors * sizeof(RGBTRIPLE));
  372.             for (i = nNumColors - 1; i >= 0; i--){
  373.                 RGBQUAD rgb;
  374.                 rgb.rgbRed      = ((RGBTRIPLE FAR *)pRgb)[i].rgbtRed;
  375.                 rgb.rgbBlue     = ((RGBTRIPLE FAR *)pRgb)[i].rgbtBlue;
  376.                 rgb.rgbGreen    = ((RGBTRIPLE FAR *)pRgb)[i].rgbtGreen;
  377.                 rgb.rgbReserved = (BYTE)0;
  378.                 pRgb[i] = rgb;
  379.             }
  380.         }
  381.         else
  382.             _lread(fh, (LPSTR)pRgb, (UINT)nNumColors * sizeof(RGBQUAD));
  383.     }
  384.     if (bf.bfOffBits != 0L){
  385.         _llseek(fh, off + bf.bfOffBits, (UINT)SEEK_SET);
  386.         }
  387.     GlobalUnlock(hbi);
  388.     return hbi;
  389. }
  390. /****************************************************************************
  391.  *                                                                          *
  392.  *  FUNCTION   :  PaletteSize(VOID FAR * pv)                                *
  393.  *                                                                          *
  394.  *  PURPOSE    :  Calculates the palette size in bytes. If the info. block  *
  395.  *                is of the BITMAPCOREHEADER type, the number of colors is  *
  396.  *                multiplied by 3 to give the palette size, otherwise the   *
  397.  *                number of colors is multiplied by 4.                                                          *
  398.  *                                                                          *
  399.  *  RETURNS    :  Palette size in number of bytes.                          *
  400.  *                                                                          *
  401.  ****************************************************************************/
  402. WORD PaletteSize (VOID FAR * pv)
  403. {
  404.     LPBITMAPINFOHEADER lpbi;
  405.     WORD               NumColors;
  406.     lpbi      = (LPBITMAPINFOHEADER)pv;
  407.     NumColors = DibNumColors(lpbi);
  408.     if (lpbi->biSize == sizeof(BITMAPCOREHEADER))
  409.         return (WORD)(NumColors * sizeof(RGBTRIPLE));
  410.     else
  411.         return (WORD)(NumColors * sizeof(RGBQUAD));
  412. }
  413. /****************************************************************************
  414.  *                                                                          *
  415.  *  FUNCTION   : DibNumColors(VOID FAR * pv)                                *
  416.  *                                                                          *
  417.  *  PURPOSE    : Determines the number of colors in the DIB by looking at   *
  418.  *               the BitCount filed in the info block.                      *
  419.  *                                                                          *
  420.  *  RETURNS    : The number of colors in the DIB.                           *
  421.  *                                                                          *
  422.  ****************************************************************************/
  423. WORD DibNumColors (VOID FAR * pv)
  424. {
  425.     INT                 bits;
  426.     LPBITMAPINFOHEADER  lpbi;
  427.     LPBITMAPCOREHEADER  lpbc;
  428.     lpbi = ((LPBITMAPINFOHEADER)pv);
  429.     lpbc = ((LPBITMAPCOREHEADER)pv);
  430.     /*  With the BITMAPINFO format headers, the size of the palette
  431.      *  is in biClrUsed, whereas in the BITMAPCORE - style headers, it
  432.      *  is dependent on the bits per pixel ( = 2 raised to the power of
  433.      *  bits/pixel).
  434.      */
  435.     if (lpbi->biSize != sizeof(BITMAPCOREHEADER)){
  436.         if (lpbi->biClrUsed != 0)
  437.             return (WORD)lpbi->biClrUsed;
  438.         bits = lpbi->biBitCount;
  439.     }
  440.     else
  441.         bits = lpbc->bcBitCount;
  442.     switch (bits){
  443.         case 1:
  444.                 return 2;
  445.         case 4:
  446.                 return 16;
  447.         case 8:
  448.                 return 256;
  449.         default:
  450.                 /* A 24 bitcount DIB has no color table */
  451.                 return 0;
  452.     }
  453. }
  454. /****************************************************************************
  455.  *                                                                          *
  456.  *  FUNCTION   : DibFromBitmap()                                            *
  457.  *                                                                          *
  458.  *  PURPOSE    : Will create a global memory block in DIB format that       *
  459.  *               represents the Device-dependent bitmap (DDB) passed in.    *
  460.  *                                                                          *
  461.  *  RETURNS    : A handle to the DIB                                        *
  462.  *                                                                          *
  463.  ****************************************************************************/
  464. HANDLE DibFromBitmap (
  465.     HBITMAP      hbm,
  466.     DWORD            biStyle,
  467.     WORD             biBits,
  468.     HPALETTE     hpal)
  469. {
  470.     BITMAP               bm;
  471.     BITMAPINFOHEADER     bi;
  472.     BITMAPINFOHEADER FAR *lpbi;
  473.     DWORD                dwLen;
  474.     HANDLE               hdib;
  475.     HANDLE               h;
  476.     HDC                  hdc;
  477.     if (!hbm)
  478.         return NULL;
  479.     if (hpal == NULL)
  480.         hpal = GetStockObject(DEFAULT_PALETTE);
  481.     GetObject(hbm,sizeof(bm),(LPSTR)&bm);
  482.     if (biBits == 0)
  483.         biBits =  bm.bmPlanes * bm.bmBitsPixel;
  484.     bi.biSize               = sizeof(BITMAPINFOHEADER);
  485.     bi.biWidth              = bm.bmWidth;
  486.     bi.biHeight             = bm.bmHeight;
  487.     bi.biPlanes             = 1;
  488.     bi.biBitCount           = biBits;
  489.     bi.biCompression        = biStyle;
  490.     bi.biSizeImage          = 0;
  491.     bi.biXPelsPerMeter      = 0;
  492.     bi.biYPelsPerMeter      = 0;
  493.     bi.biClrUsed            = 0;
  494.     bi.biClrImportant       = 0;
  495.     dwLen  = bi.biSize + PaletteSize(&bi);
  496.     hdc = GetDC(NULL);
  497.     hpal = SelectPalette(hdc,hpal,FALSE);
  498.          RealizePalette(hdc);
  499.     hdib = GlobalAlloc(GHND,dwLen);
  500.     if (!hdib){
  501.         SelectPalette(hdc,hpal,FALSE);
  502.         ReleaseDC(NULL,hdc);
  503.         return NULL;
  504.     }
  505.     lpbi = (VOID FAR *)GlobalLock(hdib);
  506.     *lpbi = bi;
  507.     /*  call GetDIBits with a NULL lpBits param, so it will calculate the
  508.      *  biSizeImage field for us
  509.      */
  510.     GetDIBits(hdc, hbm, 0L, (DWORD)bi.biHeight,
  511.         (LPBYTE)NULL, (LPBITMAPINFO)lpbi, (DWORD)DIB_RGB_COLORS);
  512.     bi = *lpbi;
  513.     GlobalUnlock(hdib);
  514.     /* If the driver did not fill in the biSizeImage field, make one up */
  515.     if (bi.biSizeImage == 0){
  516.         bi.biSizeImage = WIDTHBYTES((DWORD)bm.bmWidth * biBits) * bm.bmHeight;
  517.         if (biStyle != BI_RGB)
  518.             bi.biSizeImage = (bi.biSizeImage * 3) / 2;
  519.     }
  520.     /*  realloc the buffer big enough to hold all the bits */
  521.     dwLen = bi.biSize + PaletteSize(&bi) + bi.biSizeImage;
  522.     if (h = GlobalReAlloc(hdib,dwLen,0))
  523.         hdib = h;
  524.     else{
  525.         GlobalFree(hdib);
  526.         hdib = NULL;
  527.         SelectPalette(hdc,hpal,FALSE);
  528.         ReleaseDC(NULL,hdc);
  529.         return hdib;
  530.     }
  531.     /*  call GetDIBits with a NON-NULL lpBits param, and actualy get the
  532.      *  bits this time
  533.      */
  534.     lpbi = (VOID FAR *)GlobalLock(hdib);
  535.     if (GetDIBits( hdc,
  536.                    hbm,
  537.                    0L,
  538.                    (DWORD)bi.biHeight,
  539.                    (LPBYTE)lpbi + (WORD)lpbi->biSize + PaletteSize(lpbi),
  540.                    (LPBITMAPINFO)lpbi, (DWORD)DIB_RGB_COLORS) == 0){
  541.          GlobalUnlock(hdib);
  542.          hdib = NULL;
  543.          SelectPalette(hdc,hpal,FALSE);
  544.          ReleaseDC(NULL,hdc);
  545.          return NULL;
  546.     }
  547.     bi = *lpbi;
  548.     GlobalUnlock(hdib);
  549.     SelectPalette(hdc,hpal,FALSE);
  550.     ReleaseDC(NULL,hdc);
  551.     return hdib;
  552. }
  553. /****************************************************************************
  554.  *                                                                          *
  555.  *  FUNCTION   : BitmapFromDib(HANDLE hdib, HPALETTE hpal)                  *
  556.  *                                                                          *
  557.  *  PURPOSE    : Will create a DDB (Device Dependent Bitmap) given a global *
  558.  *               handle to a memory block in CF_DIB format                  *
  559.  *                                                                          *
  560.  *  RETURNS    : A handle to the DDB.                                       *
  561.  *                                                                          *
  562.  ****************************************************************************/
  563. HBITMAP BitmapFromDib (
  564.     HANDLE         hdib,
  565.     HPALETTE   hpal)
  566. {
  567.     LPBITMAPINFOHEADER  lpbi;
  568.     HPALETTE            hpalT;
  569.     HDC                 hdc;
  570.     HBITMAP             hbm;
  571.     StartWait();
  572.     if (!hdib)
  573.         return NULL;
  574.     lpbi = (VOID FAR *)GlobalLock(hdib);
  575.     if (!lpbi)
  576.         return NULL;
  577.     hdc = GetDC(NULL);
  578.     if (hpal){
  579.         hpalT = SelectPalette(hdc,hpal,FALSE);
  580.         RealizePalette(hdc);     // GDI Bug...????
  581.     }
  582.     hbm = CreateDIBitmap(hdc,
  583.                 (LPBITMAPINFOHEADER)lpbi,
  584.                 (LONG)CBM_INIT,
  585.                 (LPSTR)lpbi + lpbi->biSize + PaletteSize(lpbi),
  586.                 (LPBITMAPINFO)lpbi,
  587.                 DIB_RGB_COLORS );
  588.     if (hpal)
  589.         SelectPalette(hdc,hpalT,FALSE);
  590.     ReleaseDC(NULL,hdc);
  591.     GlobalUnlock(hdib);
  592.     EndWait();
  593.     return hbm;
  594. }
  595. /****************************************************************************
  596.  *                                                                          *
  597.  *  FUNCTION   : DrawBitmap(HDC hdc, int x, int y, HBITMAP hbm, DWORD rop)  *
  598.  *                                                                          *
  599.  *  PURPOSE    : Draws bitmap <hbm> at the specifed position in DC <hdc>    *
  600.  *                                                                          *
  601.  *  RETURNS    : Return value of BitBlt()                                   *
  602.  *                                                                          *
  603.  ****************************************************************************/
  604. BOOL DrawBitmap (
  605.     HDC    hdc,
  606.     INT    x,
  607.     INT    y,
  608.     HBITMAP    hbm,
  609.     DWORD          rop)
  610. {
  611.     HDC       hdcBits;
  612.     BITMAP    bm;
  613. //    HPALETTE  hpalT;  
  614.     BOOL      f;
  615.     if (!hdc || !hbm)
  616.         return FALSE;
  617.     hdcBits = CreateCompatibleDC(hdc);
  618.     GetObject(hbm,sizeof(BITMAP),(LPSTR)&bm);
  619.     SelectObject(hdcBits,hbm);
  620.     f = BitBlt(hdc,0,0,bm.bmWidth,bm.bmHeight,hdcBits,0,0,rop);
  621.     DeleteDC(hdcBits);
  622.     return f;
  623.         UNREFERENCED_PARAMETER(y);
  624.         UNREFERENCED_PARAMETER(x);
  625. }
  626. /****************************************************************************
  627.  *                                                                          *
  628.  *  FUNCTION   : DibBlt( HDC hdc,                                           *
  629.  *                       int x0, int y0,                                    *
  630.  *                       int dx, int dy,                                    *
  631.  *                       HANDLE hdib,                                       *
  632.  *                       int x1, int y1,                                    *
  633.  *                       LONG rop)                                          *
  634.  *                                                                          *
  635.  *  PURPOSE    : Draws a bitmap in CF_DIB format, using SetDIBits to device.*
  636.  *               taking the same parameters as BitBlt().                    *
  637.  *                                                                          *
  638.  *  RETURNS    : TRUE  - if function succeeds.                              *
  639.  *               FALSE - otherwise.                                         *
  640.  *                                                                          *
  641.  ****************************************************************************/
  642. BOOL DibBlt (
  643.     HDC    hdc,
  644.     INT    x0,
  645.     INT    y0,
  646.     INT    dx,
  647.     INT    dy,
  648.     HANDLE hdib,
  649.     INT    x1,
  650.     INT    y1,
  651.     LONG   rop)
  652. {
  653.     LPBITMAPINFOHEADER   lpbi;
  654. //    HPALETTE           hpal,hpalT;
  655.     LPSTR                pBuf;
  656. //    HDC                hdcMem;
  657. //    HBITMAP            hbm,hbmT;
  658.     if (!hdib)
  659.         return PatBlt(hdc,x0,y0,dx,dy,rop);
  660.     lpbi = (VOID FAR *)GlobalLock(hdib);
  661.     if (!lpbi)
  662.         return FALSE;
  663.     pBuf = (LPSTR)lpbi + (WORD)lpbi->biSize + PaletteSize(lpbi);
  664.     SetDIBitsToDevice (hdc, x0, y0, dx, dy,
  665.                        x1,y1,
  666.                        x1,
  667.                        dy,
  668.                        pBuf, (LPBITMAPINFO)lpbi,
  669.                        DIB_RGB_COLORS );
  670.     GlobalUnlock(hdib);
  671.     return TRUE;
  672. }
  673. /****************************************************************************
  674.  *                                                                          *
  675.  *  FUNCTION   : StretchDibBlt( HDC hdc,                                    *
  676.  *                              int x, int y,                               *
  677.  *                              int dx, int dy,                             *
  678.  *                              HANDLE hdib,                                *
  679.  *                              int x0, int y0,                             *
  680.  *                              int dx0, int dy0,                           *
  681.  *                              LONG rop)                                   *
  682.  *                                                                          *
  683.  *  PURPOSE    : Draws a bitmap in CF_DIB format, using StretchDIBits()     *
  684.  *               taking the same parameters as StretchBlt().                *
  685.  *                                                                          *
  686.  *  RETURNS    : TRUE  - if function succeeds.                              *
  687.  *               FALSE - otherwise.                                         *
  688.  *                                                                          *
  689.  ****************************************************************************/
  690. BOOL StretchDibBlt (
  691.     HDC hdc,
  692.     INT x,
  693.     INT y,
  694.     INT dx,
  695.     INT dy,
  696.     HANDLE hdib,
  697.     INT x0,
  698.     INT y0,
  699.     INT dx0,
  700.     INT dy0,
  701.     LONG rop)
  702. {
  703.     LPBITMAPINFOHEADER lpbi;
  704.     LPSTR        pBuf;
  705.     BOOL         f;
  706.     if (!hdib)
  707.         return PatBlt(hdc,x,y,dx,dy,rop);
  708.     lpbi = (VOID FAR *)GlobalLock(hdib);
  709.     if (!lpbi)
  710.         return FALSE;
  711.     pBuf = (LPSTR)lpbi + (WORD)lpbi->biSize + PaletteSize(lpbi);
  712.     f = StretchDIBits ( hdc,
  713.                         x, y,
  714.                         dx, dy,
  715.                         x0, y0,
  716.                         dx0, dy0,
  717.                         pBuf, (LPBITMAPINFO)lpbi,
  718.                         DIB_RGB_COLORS,
  719.                         rop);
  720.     GlobalUnlock(hdib);
  721.     return f;
  722. }
  723.  /************* PRIVATE ROUTINES TO READ/WRITE MORE THAN 64K ***************/
  724. /****************************************************************************
  725.  *                                                                          *
  726.  *  FUNCTION   : lread(int fh, VOID FAR *pv, DWORD ul)                      *
  727.  *                                                                          *
  728.  *  PURPOSE    : Reads data in steps of 32k till all the data has been read.*
  729.  *                                                                          *
  730.  *  RETURNS    : 0 - If read did not proceed correctly.                     *
  731.  *               number of bytes read otherwise.                            *
  732.  *                                                                          *
  733.  ****************************************************************************/
  734. DWORD PASCAL lread (
  735.     INT       fh,
  736.     VOID FAR      *pv,
  737.     DWORD             ul)
  738. {
  739.     DWORD     ulT = ul;
  740.     BYTE *hp = pv;
  741.     while (ul > (DWORD)MAXREAD) {
  742.         if (_lread(fh, (LPSTR)hp, (UINT)MAXREAD) != MAXREAD)
  743.                 return 0;
  744.         ul -= MAXREAD;
  745.         hp += MAXREAD;
  746.     }
  747.     if (_lread(fh, (LPSTR)hp, (UINT)ul) != (UINT)ul)
  748.         return 0;
  749.     return ulT;
  750. }
  751. /****************************************************************************
  752.  *                                                                          *
  753.  *  FUNCTION   : lwrite(int fh, VOID FAR *pv, DWORD ul)                     *
  754.  *                                                                          *
  755.  *  PURPOSE    : Writes data in steps of 32k till all the data is written.  *
  756.  *                                                                          *
  757.  *  RETURNS    : 0 - If write did not proceed correctly.                    *
  758.  *               number of bytes written otherwise.                         *
  759.  *                                                                          *
  760.  ****************************************************************************/
  761. DWORD PASCAL lwrite (
  762.     INT      fh,
  763.     VOID FAR     *pv,
  764.     DWORD            ul)
  765. {
  766.     DWORD     ulT = ul;
  767.     BYTE *hp = pv;
  768.     while (ul > MAXREAD) {
  769.         if (_lwrite(fh, (LPSTR)hp, (UINT)MAXREAD) != MAXREAD)
  770.                 return 0;
  771.         ul -= MAXREAD;
  772.         hp += MAXREAD;
  773.     }
  774.     if (_lwrite(fh, (LPSTR)hp, (UINT)ul) != (UINT)ul)
  775.         return 0;                 
  776.     return ulT;
  777. }
  778. /****************************************************************************
  779.  *                                                                          *
  780.  *  FUNCTION   : ReadBitMapFileHeaderandConvertToDwordAlign(HFILE fh, LPBITMAPFILEHEADER pbf)
  781.  *                                                                          *
  782.  *  PURPOSE    : read file header (which is packed) and convert into unpacked BITMAPFILEHEADER strucutre
  783.  *                                                                          *
  784.  *  RETURNS    : VOID
  785.  *                                                                          *
  786.  ****************************************************************************/
  787. VOID ReadBitMapFileHeaderandConvertToDwordAlign(HFILE fh, LPBITMAPFILEHEADER pbf, LPDWORD lpdwoff)
  788. {
  789.         DWORD off;
  790.         off = _llseek(fh, 0L, (UINT) SEEK_CUR);
  791.         *lpdwoff = off;
  792. /*              BITMAPFILEHEADER STRUCUTURE is as follows 
  793.  *              BITMAPFILEHEADER
  794.  *              WORD    bfType 
  795.  >          ....                  <     add WORD if packed here!
  796.  *              DWORD   bfSize 
  797.  *              WORD    bfReserved1
  798.  *              WORD    bfReserved2
  799.  *              DWORD   bfOffBits 
  800.  *                      This is the packed format, unpacked adds a WORD after bfType
  801.  */
  802.         /* read in bfType*/
  803.         _lread(fh, (LPSTR) &pbf->bfType, sizeof(WORD));
  804.         /* read in last 3 dwords*/
  805.         _lread(fh, (LPSTR) &pbf->bfSize, sizeof(DWORD) * 3);
  806. }
  807. /****************************************************************************
  808.  *                                                                          *
  809.  *  FUNCTION   : WriteMapFileHeaderandConvertFromDwordAlignToPacked(HFILE fh, LPBITMAPFILEHEADER pbf)
  810.  *                                                                          *
  811.  *  PURPOSE    : write header structure (which NOT packed) and write it PACKED
  812.  *                                                                          *
  813.  *  RETURNS    : VOID
  814.  *                                                                          *
  815.  ****************************************************************************/
  816. VOID WriteMapFileHeaderandConvertFromDwordAlignToPacked(HFILE fh, LPBITMAPFILEHEADER pbf)
  817. {
  818.         /* write bfType*/
  819.     _lwrite(fh, (LPSTR)&pbf->bfType, (UINT)sizeof (WORD));
  820.         /* now pass over extra word, and only write next 3 DWORDS!*/
  821.         _lwrite(fh, (LPSTR)&pbf->bfSize, sizeof(DWORD) * 3);
  822. }