home *** CD-ROM | disk | FTP | other *** search
/ Point Programming 1 / PPROG1.ISO / misc / vfwdk / samples / icmapp / dib.c next >
Encoding:
C/C++ Source or Header  |  1993-01-31  |  16.0 KB  |  660 lines

  1. /*----------------------------------------------------------------------------*\
  2. |   Routines for dealing with Device independent bitmaps                       |
  3. |                                           |
  4. |    (C) Copyright Microsoft Corp. 1991, 1992, 1993.  All rights reserved.
  5. |
  6. |    You have a royalty-free right to use, modify, reproduce and
  7. |    distribute the Sample Files (and/or any modified version) in
  8. |    any way you find useful, provided that you agree that
  9. |    Microsoft has no warranty obligations or liability for any
  10. |    Sample Application Files.
  11. |                                                                              |
  12. \*----------------------------------------------------------------------------*/
  13.  
  14. #include <windows.h>
  15. #include "dib.h"
  16.  
  17. /* flags for _lseek */
  18. #define  SEEK_CUR 1
  19. #define  SEEK_END 2
  20. #define  SEEK_SET 0
  21.  
  22. #define BFT_ICON   0x4349   /* 'IC' */
  23. #define BFT_BITMAP 0x4d42   /* 'BM' */
  24. #define BFT_CURSOR 0x5450   /* 'PT' */
  25.  
  26. #define ISDIB(bft) ((bft) == BFT_BITMAP)
  27.  
  28. #define PALVERSION      0x300
  29. #define MAXPALETTE      256
  30.  
  31. /*
  32.  *   Open a DIB file and return a MEMORY DIB, a memory handle containing..
  33.  *
  34.  *   BITMAP INFO    bi
  35.  *   palette data
  36.  *   bits....
  37.  *
  38.  */
  39. HDIB OpenDIB(LPSTR szFile)
  40. {
  41.     int            fh;
  42.     LPBITMAPINFOHEADER  lpbi;
  43.     DWORD        dwLen;
  44.     HDIB                hdib;
  45.     HANDLE              h;
  46.     OFSTRUCT            of;
  47.  
  48.     if (HIWORD((DWORD)szFile) == 0)
  49.     {
  50.         fh = LOWORD((DWORD)szFile);
  51.     }
  52.     else
  53.     {
  54.         fh = OpenFile(szFile, &of, OF_READ);
  55.     }
  56.  
  57.     if (fh == -1)
  58.     return NULL;
  59.  
  60.     hdib = ReadDibBitmapInfo(fh);
  61.  
  62.     if (!hdib)
  63.     return NULL;
  64.  
  65.     lpbi = (LPVOID)GlobalLock(hdib);
  66.  
  67.     /* How much memory do we need to hold the DIB */
  68.  
  69.     dwLen  = DibSize(lpbi);
  70.  
  71.     /* Can we get more memory? */
  72.  
  73.     h = GlobalReAlloc(hdib,dwLen,0);
  74.  
  75.     if (!h)
  76.     {
  77.     GlobalFree(hdib);
  78.     hdib = NULL;
  79.     }
  80.     else
  81.     {
  82.     hdib = h;
  83.     }
  84.  
  85.     if (hdib)
  86.     {
  87.         lpbi = (LPVOID)GlobalLock(hdib);
  88.  
  89.     /* read in the bits */
  90.         _hread(fh, DibPtr(lpbi), lpbi->biSizeImage);
  91.     }
  92.  
  93.     if (HIWORD((DWORD)szFile) != 0)
  94.         _lclose(fh);
  95.  
  96.     return hdib;
  97. }
  98.  
  99. /*
  100.  *   Write a global handle in CF_DIB format to a file.
  101.  *
  102.  */
  103. BOOL WriteDIB(LPSTR szFile,HDIB hdib)
  104. {
  105.     BITMAPFILEHEADER    hdr;
  106.     LPBITMAPINFOHEADER  lpbi;
  107.     int                 fh;
  108.     OFSTRUCT            of;
  109.  
  110.     if (!hdib)
  111.     return FALSE;
  112.  
  113.     if (HIWORD((DWORD)szFile) == 0)
  114.     {
  115.         fh = LOWORD((DWORD)szFile);
  116.     }
  117.     else
  118.     {
  119.         fh = OpenFile(szFile,&of,OF_CREATE|OF_READWRITE);
  120.     }
  121.  
  122.     if (fh == -1)
  123.         return FALSE;
  124.  
  125.     lpbi = (LPVOID)GlobalLock(hdib);
  126.  
  127.     hdr.bfType        = BFT_BITMAP;
  128.     hdr.bfSize          = DibSize(lpbi) + sizeof(BITMAPFILEHEADER);
  129.     hdr.bfReserved1     = 0;
  130.     hdr.bfReserved2     = 0;
  131.     hdr.bfOffBits       = (DWORD)sizeof(BITMAPFILEHEADER) +
  132.                           lpbi->biSize + lpbi->biClrUsed * sizeof(RGBQUAD);
  133.  
  134.     _lwrite(fh,(LPVOID)&hdr,sizeof(BITMAPFILEHEADER));
  135.     _hwrite(fh,(LPVOID)lpbi,DibSize(lpbi));
  136.  
  137.     GlobalUnlock(hdib);
  138.  
  139.     if (HIWORD((DWORD)szFile) != 0)
  140.         _lclose(fh);
  141.  
  142.     return TRUE;
  143. }
  144.  
  145. /*
  146.  *  CreateBIPalette()
  147.  *
  148.  *  Given a Pointer to a BITMAPINFO struct will create a
  149.  *  a GDI palette object from the color table.
  150.  *
  151.  */
  152. HPALETTE CreateBIPalette(LPBITMAPINFOHEADER lpbi)
  153. {
  154.     LOGPALETTE          *pPal;
  155.     HPALETTE            hpal = NULL;
  156.     WORD                nNumColors;
  157.     int                 i;
  158.     RGBQUAD        FAR *pRgb;
  159.  
  160.     if (!lpbi)
  161.     return NULL;
  162.  
  163.     nNumColors = DibNumColors(lpbi);
  164.  
  165.     if (nNumColors)
  166.     {
  167.         pRgb = DibColors(lpbi);
  168.     pPal = (LOGPALETTE*)LocalAlloc(LPTR,sizeof(LOGPALETTE) + nNumColors * sizeof(PALETTEENTRY));
  169.  
  170.         if (!pPal)
  171.             goto exit;
  172.  
  173.         pPal->palNumEntries = nNumColors;
  174.     pPal->palVersion    = PALVERSION;
  175.  
  176.         for (i = 0; i < (int)nNumColors; i++)
  177.     {
  178.         pPal->palPalEntry[i].peRed     = pRgb->rgbRed;
  179.         pPal->palPalEntry[i].peGreen = pRgb->rgbGreen;
  180.         pPal->palPalEntry[i].peBlue  = pRgb->rgbBlue;
  181.         pPal->palPalEntry[i].peFlags = (BYTE)0;
  182.             pRgb++;
  183.         }
  184.  
  185.         hpal = CreatePalette(pPal);
  186.         LocalFree((HANDLE)pPal);
  187.     }
  188.  
  189. exit:
  190.     return hpal;
  191. }
  192.  
  193. /*
  194.  *  ReadDibBitmapInfo()
  195.  *
  196.  *  Will read a file in DIB format and return a global HANDLE to it's
  197.  *  BITMAPINFO.  This function will work with both "old" and "new"
  198.  *  bitmap formats, but will allways return a "new" BITMAPINFO
  199.  *
  200.  */
  201. HDIB ReadDibBitmapInfo(int fh)
  202. {
  203.     DWORD     off;
  204.     HDIB    hbi = NULL;
  205.     int       size;
  206.     int       i;
  207.     WORD      nNumColors;
  208.  
  209.     RGBQUAD FAR       *pRgb;
  210.     BITMAPINFOHEADER   bi;
  211.     BITMAPCOREHEADER   bc;
  212.     LPBITMAPINFOHEADER lpbi;
  213.     BITMAPFILEHEADER   bf;
  214.  
  215.     if (fh == -1)
  216.         return NULL;
  217.  
  218.     off = _llseek(fh,0L,SEEK_CUR);
  219.  
  220.     if (sizeof(bf) != _lread(fh,(LPVOID)&bf,sizeof(bf)))
  221.         return FALSE;
  222.  
  223.     /*
  224.      *  do we have a RC HEADER?
  225.      */
  226.     if (!ISDIB(bf.bfType))
  227.     {
  228.         bf.bfOffBits = 0L;
  229.         _llseek(fh,off,SEEK_SET);
  230.     }
  231.  
  232.     if (sizeof(bi) != _lread(fh,(LPVOID)&bi,sizeof(bi)))
  233.         return FALSE;
  234.  
  235.     nNumColors = DibNumColors(&bi);
  236.  
  237.     /*
  238.      *  what type of bitmap info is this?
  239.      */
  240.     switch (size = (int)bi.biSize)
  241.     {
  242.         default:
  243.         case sizeof(BITMAPINFOHEADER):
  244.             break;
  245.  
  246.         case sizeof(BITMAPCOREHEADER):
  247.             bc = *(BITMAPCOREHEADER*)&bi;
  248.             bi.biSize               = sizeof(BITMAPINFOHEADER);
  249.             bi.biWidth              = (DWORD)bc.bcWidth;
  250.             bi.biHeight             = (DWORD)bc.bcHeight;
  251.             bi.biPlanes             =  (WORD)bc.bcPlanes;
  252.             bi.biBitCount           =  (WORD)bc.bcBitCount;
  253.             bi.biCompression        = BI_RGB;
  254.             bi.biSizeImage          = 0;
  255.             bi.biXPelsPerMeter      = 0;
  256.             bi.biYPelsPerMeter      = 0;
  257.             bi.biClrUsed            = nNumColors;
  258.             bi.biClrImportant       = nNumColors;
  259.  
  260.             _llseek(fh,(LONG)sizeof(BITMAPCOREHEADER)-sizeof(BITMAPINFOHEADER),SEEK_CUR);
  261.  
  262.             break;
  263.     }
  264.  
  265.     /*
  266.      *    fill in some default values!
  267.      */
  268.     if (bi.biSizeImage == 0)
  269.         bi.biSizeImage = DibSizeImage(&bi);
  270.  
  271.     if (bi.biClrUsed == 0)
  272.     bi.biClrUsed = DibNumColors(&bi);
  273.  
  274.     hbi = GlobalAlloc(GMEM_MOVEABLE,(LONG)bi.biSize + nNumColors * sizeof(RGBQUAD));
  275.  
  276.     if (!hbi)
  277.         return NULL;
  278.  
  279.     lpbi = (VOID FAR *)GlobalLock(hbi);
  280.     *lpbi = bi;
  281.  
  282.     pRgb = DibColors(lpbi);
  283.  
  284.     if (nNumColors)
  285.     {
  286.         if (size == sizeof(BITMAPCOREHEADER))
  287.         {
  288.             /*
  289.              * convert a old color table (3 byte entries) to a new
  290.              * color table (4 byte entries)
  291.              */
  292.             _lread(fh,(LPSTR)pRgb,nNumColors * sizeof(RGBTRIPLE));
  293.  
  294.             for (i=nNumColors-1; i>=0; i--)
  295.             {
  296.                 RGBQUAD rgb;
  297.  
  298.                 rgb.rgbRed      = ((RGBTRIPLE FAR *)pRgb)[i].rgbtRed;
  299.                 rgb.rgbBlue     = ((RGBTRIPLE FAR *)pRgb)[i].rgbtBlue;
  300.                 rgb.rgbGreen    = ((RGBTRIPLE FAR *)pRgb)[i].rgbtGreen;
  301.                 rgb.rgbReserved = (BYTE)0;
  302.  
  303.                 pRgb[i] = rgb;
  304.             }
  305.         }
  306.         else
  307.         {
  308.             _lread(fh,(LPSTR)pRgb,nNumColors * sizeof(RGBQUAD));
  309.         }
  310.     }
  311.  
  312.     if (bf.bfOffBits != 0L)
  313.         _llseek(fh,off + bf.bfOffBits,SEEK_SET);
  314.  
  315.     return hbi;
  316. }
  317.  
  318. /*
  319.  *  DibFromBitmap()
  320.  *
  321.  *  Will create a global memory block in DIB format that represents the DDB
  322.  *  passed in
  323.  *
  324.  */
  325. HDIB DibFromBitmap(HBITMAP hbm, DWORD biStyle, WORD biBits, HPALETTE hpal, WORD wUsage)
  326. {
  327.     BITMAP               bm;
  328.     BITMAPINFOHEADER     bi;
  329.     BITMAPINFOHEADER FAR *lpbi;
  330.     DWORD                dwLen;
  331.     int                  nColors;
  332.     HDIB                 hdib;
  333.     HANDLE               h;
  334.     HDC                  hdc;
  335.  
  336.     if (!hbm)
  337.         return NULL;
  338.  
  339.     if (hpal == NULL)
  340.         hpal = GetStockObject(DEFAULT_PALETTE);
  341.  
  342.     GetObject(hbm,sizeof(bm),(LPSTR)&bm);
  343.     GetObject(hpal,sizeof(nColors),(LPSTR)&nColors);
  344.  
  345.     if (biBits == 0)
  346.         biBits = bm.bmPlanes * bm.bmBitsPixel;
  347.  
  348.     bi.biSize               = sizeof(BITMAPINFOHEADER);
  349.     bi.biWidth              = bm.bmWidth;
  350.     bi.biHeight             = bm.bmHeight;
  351.     bi.biPlanes             = 1;
  352.     bi.biBitCount           = biBits;
  353.     bi.biCompression        = biStyle;
  354.     bi.biSizeImage          = 0;
  355.     bi.biXPelsPerMeter      = 0;
  356.     bi.biYPelsPerMeter      = 0;
  357.     bi.biClrUsed            = 0;
  358.     bi.biClrImportant       = 0;
  359.  
  360.     dwLen  = bi.biSize + DibNumColors(&bi) * sizeof(RGBQUAD);
  361.  
  362.     hdc = CreateCompatibleDC(NULL);
  363.     hpal = SelectPalette(hdc,hpal,FALSE);
  364.     RealizePalette(hdc);  // why is this needed on a MEMORY DC? GDI bug??
  365.  
  366.     hdib = GlobalAlloc(GMEM_MOVEABLE,dwLen);
  367.  
  368.     if (!hdib)
  369.         goto exit;
  370.  
  371.     lpbi = (VOID FAR *)GlobalLock(hdib);
  372.  
  373.     *lpbi = bi;
  374.  
  375.     /*
  376.      *  call GetDIBits with a NULL lpBits param, so it will calculate the
  377.      *  biSizeImage field for us
  378.      */
  379.     GetDIBits(hdc, hbm, 0, (WORD)bi.biHeight,
  380.         NULL, (LPBITMAPINFO)lpbi, wUsage);
  381.  
  382.     bi = *lpbi;
  383.  
  384.     /*
  385.      * If the driver did not fill in the biSizeImage field, fill it in
  386.      * based on the width, height and bit depth.
  387.      */
  388.     if (bi.biSizeImage == 0)
  389.     {
  390.         bi.biSizeImage = (DWORD)WIDTHBYTES(bm.bmWidth * biBits) * bm.bmHeight;
  391.  
  392.         if (biStyle != BI_RGB)
  393.             bi.biSizeImage = (bi.biSizeImage * 3) / 2;
  394.     }
  395.  
  396.     /*
  397.      *  realloc the buffer big enough to hold all the bits
  398.      */
  399.     dwLen = bi.biSize + DibNumColors(&bi) * sizeof(RGBQUAD) + bi.biSizeImage;
  400.  
  401.     if (h = GlobalReAlloc(hdib,dwLen,0))
  402.     {
  403.         hdib = h;
  404.     }
  405.     else
  406.     {
  407.         GlobalFree(hdib);
  408.         hdib = NULL;
  409.         goto exit;
  410.     }
  411.  
  412.     /*
  413.      *  call GetDIBits with a NON-NULL lpBits param, and actualy get the
  414.      *  bits this time
  415.      */
  416.     lpbi = (VOID FAR *)GlobalLock(hdib);
  417.  
  418.     GetDIBits(hdc, hbm, 0, (WORD)bi.biHeight,
  419.         DibPtr(lpbi),(LPBITMAPINFO)lpbi, wUsage);
  420.  
  421.     bi = *lpbi;
  422.     lpbi->biClrUsed = DibNumColors(lpbi);
  423.  
  424. exit:
  425.     SelectPalette(hdc,hpal,FALSE);
  426.     DeleteDC(hdc);
  427.     return hdib;
  428. }
  429.  
  430. /*
  431.  *  BitmapFromDib()
  432.  *
  433.  *  Will create a DDB (Device Dependent Bitmap) given a global handle to
  434.  *  a memory block in CF_DIB format
  435.  *
  436.  */
  437. HBITMAP BitmapFromDib(HDIB hdib, HPALETTE hpal, WORD wUsage)
  438. {
  439.     LPBITMAPINFOHEADER lpbi;
  440.     HPALETTE    hpalT;
  441.     HDC         hdc;
  442.     HBITMAP     hbm;
  443.  
  444.     if (!hdib)
  445.         return NULL;
  446.  
  447.     lpbi = (LPVOID)GlobalLock(hdib);
  448.  
  449.     if (!lpbi)
  450.     return NULL;
  451.  
  452.     hdc = GetDC(NULL);
  453.  
  454.     if (hpal)
  455.     {
  456.         hpalT = SelectPalette(hdc,hpal,FALSE);
  457.         RealizePalette(hdc);
  458.     }
  459.  
  460.     hbm = CreateDIBitmap(hdc,(LPBITMAPINFOHEADER)lpbi,(LONG)CBM_INIT,
  461.                 DibPtr(lpbi),(LPBITMAPINFO)lpbi,wUsage);
  462.  
  463.     if (hpal && hpalT)
  464.         SelectPalette(hdc,hpalT,FALSE);
  465.  
  466.     ReleaseDC(NULL,hdc);
  467.  
  468.     return hbm;
  469. }
  470.  
  471. /*
  472.  *  SetDibUsage(hdib,hpal,wUsage)
  473.  *
  474.  *  Modifies the color table of the passed DIB for use with the wUsage
  475.  *  parameter specifed.
  476.  *
  477.  *  if wUsage is DIB_PAL_COLORS the DIB color table is set to 0-256
  478.  *  if wUsage is DIB_RGB_COLORS the DIB color table is set to the RGB values
  479.  *      in the passed palette
  480.  *
  481.  */
  482. BOOL SetDibUsage(HDIB hdib, HPALETTE hpal,WORD wUsage)
  483. {
  484.     LPBITMAPINFOHEADER lpbi;
  485.     PALETTEENTRY       ape[MAXPALETTE];
  486.     RGBQUAD FAR *      pRgb;
  487.     WORD FAR *         pw;
  488.     int                nColors;
  489.     int                n;
  490.  
  491.     if (hpal == NULL)
  492.         hpal = GetStockObject(DEFAULT_PALETTE);
  493.  
  494.     if (!hdib)
  495.         return FALSE;
  496.  
  497.     lpbi = (VOID FAR *)GlobalLock(hdib);
  498.  
  499.     if (!lpbi)
  500.     return FALSE;
  501.  
  502.     nColors = DibNumColors(lpbi);
  503.  
  504.     if (nColors > 0)
  505.     {
  506.         pRgb = (RGBQUAD FAR *)((LPSTR)lpbi + (WORD)lpbi->biSize);
  507.  
  508.         switch (wUsage)
  509.         {
  510.             //
  511.             // Set the DIB color table to palette indexes
  512.             //
  513.             case DIB_PAL_COLORS:
  514.                 for (pw = (WORD FAR*)pRgb,n=0; n<nColors; n++,pw++)
  515.                     *pw = n;
  516.                 break;
  517.  
  518.             //
  519.             // Set the DIB color table to RGBQUADS
  520.             //
  521.             default:
  522.             case DIB_RGB_COLORS:
  523.                 nColors = min(nColors,MAXPALETTE);
  524.  
  525.                 GetPaletteEntries(hpal,0,nColors,ape);
  526.  
  527.                 for (n=0; n<nColors; n++)
  528.                 {
  529.                     pRgb[n].rgbRed      = ape[n].peRed;
  530.                     pRgb[n].rgbGreen    = ape[n].peGreen;
  531.                     pRgb[n].rgbBlue     = ape[n].peBlue;
  532.                     pRgb[n].rgbReserved = 0;
  533.                 }
  534.                 break;
  535.         }
  536.     }
  537.     return TRUE;
  538. }
  539.  
  540. HDIB CreateDib(int bits, int dx, int dy)
  541. {
  542.     HDIB                hdib;
  543.     BITMAPINFOHEADER    bi;
  544.     LPBITMAPINFOHEADER  lpbi;
  545.     DWORD FAR *         pRgb;
  546.     int                 i;
  547.  
  548.     //
  549.     // These are the standard VGA colors, we will be stuck with until the
  550.     // end of time!
  551.     //
  552.     static DWORD CosmicColors[16] = {
  553.          0x00000000        // 0000  black
  554.         ,0x00800000        // 0001  dark red
  555.         ,0x00008000        // 0010  dark green
  556.         ,0x00808000        // 0011  mustard
  557.         ,0x00000080        // 0100  dark blue
  558.         ,0x00800080        // 0101  purple
  559.         ,0x00008080        // 0110  dark turquoise
  560.         ,0x00C0C0C0        // 1000  gray
  561.         ,0x00808080        // 0111  dark gray
  562.         ,0x00FF0000        // 1001  red
  563.         ,0x0000FF00        // 1010  green
  564.         ,0x00FFFF00        // 1011  yellow
  565.         ,0x000000FF        // 1100  blue
  566.         ,0x00FF00FF        // 1101  pink (magenta)
  567.         ,0x0000FFFF        // 1110  cyan
  568.         ,0x00FFFFFF        // 1111  white
  569.         };
  570.  
  571.     bi.biSize           = sizeof(BITMAPINFOHEADER);
  572.     bi.biPlanes         = 1;
  573.     bi.biBitCount       = bits;
  574.     bi.biWidth          = dx;
  575.     bi.biHeight         = dy;
  576.     bi.biCompression    = BI_RGB;
  577.     bi.biSizeImage      = 0;
  578.     bi.biXPelsPerMeter  = 0;
  579.     bi.biYPelsPerMeter  = 0;
  580.     bi.biClrUsed    = 0;
  581.     bi.biClrImportant   = 0;
  582.     bi.biClrUsed    = DibNumColors(&bi);
  583.  
  584.     hdib = GlobalAlloc(GMEM_MOVEABLE,sizeof(BITMAPINFOHEADER) +
  585.                 + (long)bi.biClrUsed * sizeof(RGBQUAD)
  586.                 + (long)DIBWIDTHBYTES(bi) * (long)dy);
  587.  
  588.     if (hdib)
  589.     {
  590.         lpbi  = (LPVOID)GlobalLock(hdib);
  591.         *lpbi = bi;
  592.  
  593.         pRgb  = (LPVOID)DibColors(lpbi);
  594.  
  595.         //
  596.         //  setup the color table
  597.         //
  598.         if (bits == 1)
  599.         {
  600.             pRgb[0] = CosmicColors[0];
  601.             pRgb[1] = CosmicColors[15];
  602.         }
  603.         else
  604.         {
  605.             for (i=0; i<16; i++)
  606.                 pRgb[i] = CosmicColors[i%16];
  607.         }
  608.     }
  609.  
  610.     return hdib;
  611. }
  612.  
  613. /*
  614.  *  StretchDib()
  615.  *
  616.  *  draws a bitmap in CF_DIB format, using StretchDIBits()
  617.  *
  618.  *  takes the same parameters as StretchBlt()
  619.  */
  620. BOOL StretchDib(HDC hdc, int x, int y, int dx, int dy, HDIB hdib, HPALETTE hpal, int x0, int y0, int dx0, int dy0, LONG rop, WORD wUsage)
  621. {
  622.     LPBITMAPINFOHEADER  lpbi;
  623.     HPALETTE            hpalT;
  624.     BOOL                f;
  625.  
  626.     if (!hdib)
  627.         return PatBlt(hdc,x,y,dx,dy,rop);
  628.  
  629.     if (hpal)
  630.     {
  631.         hpalT = SelectPalette(hdc, hpal, FALSE);
  632.         RealizePalette(hdc);
  633.     }
  634.  
  635.     lpbi = (LPVOID)GlobalLock(hdib);
  636.  
  637.     if (!lpbi)
  638.         return FALSE;
  639.  
  640.     if (dx0 == -1 && dy0 == -1)
  641.     {
  642.         dx0 = (int)lpbi->biWidth;
  643.         dy0 = (int)lpbi->biHeight;
  644.     }
  645.  
  646.     if (dx < 0 && dy < 0)
  647.     {
  648.         dx = dx0 * (-dx);
  649.         dy = dy0 * (-dy);
  650.     }
  651.  
  652.     f = StretchDIBits(hdc,x,y,dx,dy,x0,y0,dx0,dy0,
  653.         DibPtr(lpbi), (LPBITMAPINFO)lpbi,wUsage,rop) > 0;
  654.  
  655.     if (hpal && hpalT)
  656.         SelectObject(hdc, hpalT);
  657.  
  658.     return f;
  659. }
  660.