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

Windows编程

开发平台:

Visual C++

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