DIBUTILS.CPP
上传用户:wep9318
上传日期:2007-01-07
资源大小:893k
文件大小:20k
源码类别:

图片显示

开发平台:

Visual C++

  1. /**************************************************************************
  2.  UTILS.C - useful functions for WinG Sample Apps
  3.  **************************************************************************/
  4. /**************************************************************************
  5.  (C) Copyright 1994 Microsoft Corp.  All rights reserved.
  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 which are modified. 
  11.  **************************************************************************/
  12. /*----------------------------------------------------------------------------*
  13. |   Functions for handling Device Independent Bitmaps and clearing the         |
  14. |   System Palette.                                                            |
  15. *----------------------------------------------------------------------------*/
  16. #include "stdafx.h"
  17. #include <windows.h>
  18. #include <windowsx.h>
  19. #include <stdio.h>
  20. #include "dibutils.h"
  21. #if defined(WIN32) || defined(_WIN32)
  22.     #include <memory.h>             // for _fmemcpy()
  23.  #define _huge
  24. #ifndef hmemcpy
  25.     #define hmemcpy memcpy
  26. #endif
  27. #endif
  28. #define BFT_ICON   0x4349   /* 'IC' */
  29. #define BFT_BITMAP 0x4d42   /* 'BM' */
  30. #define BFT_CURSOR 0x5450   /* 'PT' */
  31. /* flags for _lseek */
  32. #define  SEEK_CUR 1
  33. #define  SEEK_END 2
  34. #define  SEEK_SET 0
  35. /*
  36.  *  Clear the System Palette so that we can ensure an identity palette 
  37.  *  mapping for fast performance.
  38.  */
  39. void ClearSystemPalette(void)
  40. {
  41.   //*** A dummy palette setup
  42.   struct
  43.   {
  44.     WORD Version;
  45.     WORD NumberOfEntries;
  46.     PALETTEENTRY aEntries[256];
  47.   } Palette =
  48.   {
  49.     0x300,
  50.     256
  51.   };
  52.   HPALETTE ScreenPalette = 0;
  53.   HDC ScreenDC;
  54.   int Counter;
  55.   UINT nMapped = 0;
  56.   BOOL bOK = FALSE;
  57.   int  nOK = 0;
  58.   
  59.   //*** Reset everything in the system palette to black
  60.   for(Counter = 0; Counter < 256; Counter++)
  61.   {
  62.     Palette.aEntries[Counter].peRed = 0;
  63.  Palette.aEntries[Counter].peGreen = 0;
  64.     Palette.aEntries[Counter].peBlue = 0;
  65.     Palette.aEntries[Counter].peFlags = PC_NOCOLLAPSE;
  66.   }
  67.   //*** Create, select, realize, deselect, and delete the palette
  68.   ScreenDC = GetDC(NULL);
  69.   ScreenPalette = CreatePalette((LOGPALETTE *)&Palette);
  70.   if (ScreenPalette)
  71.   {
  72.  ScreenPalette = SelectPalette(ScreenDC,ScreenPalette,FALSE);
  73.  nMapped = RealizePalette(ScreenDC);
  74.     ScreenPalette = SelectPalette(ScreenDC,ScreenPalette,FALSE);
  75.     bOK = DeleteObject(ScreenPalette);
  76.   }
  77.   nOK = ReleaseDC(NULL, ScreenDC);
  78.   return;
  79. }
  80. /*
  81.  *   Open a DIB file and return a MEMORY DIB, a memory handle containing..
  82.  *
  83.  *   BITMAP INFO    bi
  84.  *   palette data
  85.  *   bits....
  86.  */
  87. int DibWriteFile(LPSTR szFile, LPBITMAPINFOHEADER lpbi)
  88. {
  89.  HFILE               fh;
  90.  OFSTRUCT            of;
  91.  fh = OpenFile(szFile, &of, OF_WRITE | OF_CREATE);
  92.   if (!fh) {
  93. //  printf("la regamos0");
  94.  return 0;
  95.   }
  96.   long size = DibSize(lpbi);
  97.   // write file header
  98.   BITMAPFILEHEADER bmf;
  99.   bmf.bfType = 'BM';
  100.   bmf.bfSize = sizeof(bmf) + size;
  101.   bmf.bfReserved1 = 0;
  102.   bmf.bfReserved2 = 0;
  103.   bmf.bfOffBits = sizeof(bmf) + (char far*)(DibPtr(lpbi)) - (char far*)lpbi;
  104. #if defined( __WATCOMC__) || defined(_MSC_VER)
  105.   if (_hwrite(fh, (LPCSTR)(&bmf), sizeof(bmf))<0 ||
  106. _hwrite(fh, (LPCSTR)lpbi, size)<0) {
  107.   _lclose(fh);
  108. //  printf("la regamos1");
  109.   return 0;
  110.   }
  111. #else
  112.   if (_hwrite(fh, (LPBYTE)(&bmf), sizeof(bmf))<0 ||
  113. _hwrite(fh, (LPBYTE)lpbi, size)<0) {
  114.   _lclose(fh);
  115. //  printf("la regamos1");
  116.   return 0;
  117.   }
  118. #endif
  119.   _lclose(fh);
  120.   return 1;
  121. }
  122. // The following is an alternative implementation of DIB writing, since
  123. // the above doesn't appear to work.
  124. /****************************************************************************
  125.  *     *
  126.  *  FUNCTION   :  PaletteSize(VOID FAR * pv)     *
  127.  *     *
  128.  *  PURPOSE    :  Calculates the palette size in bytes. If the info. block  *
  129.  *   is of the BITMAPCOREHEADER type, the number of colors is  *
  130.  *   multiplied by 3 to give the palette size, otherwise the   *
  131.  *   number of colors is multiplied by 4. *
  132.  *     *
  133.  *  RETURNS    :  Palette size in number of bytes.     *
  134.  *     *
  135.  ****************************************************************************/
  136. WORD PaletteSize(VOID FAR * pv)
  137. {
  138. LPBITMAPINFOHEADER lpbi;
  139. WORD        NumColors;
  140. lpbi = (LPBITMAPINFOHEADER) pv;
  141. NumColors = DibNumColors(lpbi);
  142. if (lpbi->biSize == sizeof(BITMAPCOREHEADER))
  143. return NumColors * sizeof(RGBTRIPLE);
  144. else 
  145. return NumColors * sizeof(RGBQUAD);
  146. }
  147. /****************************************************************************
  148.  *     *
  149.  *  FUNCTION   : lwrite(int fh, VOID FAR *pv, DWORD ul)      *
  150.  *     *
  151.  *  PURPOSE    : Writes data in steps of 32k till all the data is written.  *
  152.  *     *
  153.  *  RETURNS    : 0 - If write did not proceed correctly.     *
  154.  *  number of bytes written otherwise.     *
  155.  *     *
  156.  ****************************************************************************/
  157. #define MAXREAD  32768  /* Number of bytes to be read during */
  158.  /* each read operation.  */
  159. DWORD PASCAL lwrite(int fh, VOID FAR *pv, DWORD ul)
  160. {
  161. DWORD     ulT = ul;
  162. #if defined(WINNT) || defined(WIN32) || defined(__WIN32__)
  163. BYTE *hp = (BYTE *) pv;
  164. #else
  165. BYTE huge *hp = (BYTE huge *) pv;
  166. #endif
  167. while (ul > MAXREAD) {
  168. if (_lwrite(fh, (LPSTR) hp, (WORD) MAXREAD) != MAXREAD)
  169. return 0;
  170. ul -= MAXREAD;
  171. hp += MAXREAD;
  172. }
  173. if (_lwrite(fh, (LPSTR) hp, (WORD) ul) != (WORD) ul)
  174. return 0;
  175. return ulT;
  176. }
  177. /****************************************************************************
  178.  *     *
  179.  *  FUNCTION   : WriteDIB(LPSTR szFile,HANDLE hdib)     *
  180.  *     *
  181.  *  PURPOSE    : Write a global handle in CF_DIB format to a file.     *
  182.  *     *
  183.  *  RETURNS    : TRUE  - if successful.      *
  184.  *  FALSE - otherwise     *
  185.  *     *
  186.  ****************************************************************************/
  187. BOOL WriteDIB(const char *szFile, LPBITMAPINFOHEADER  lpbi)
  188. {
  189. BITMAPFILEHEADER hdr;
  190. int                 fh;
  191. OFSTRUCT            of;
  192. if (!lpbi)
  193. return FALSE;
  194. fh = OpenFile(szFile, &of, OF_CREATE | OF_READWRITE);
  195. if (fh == -1)
  196. return FALSE;
  197.     /* Fill in the fields of the file header */
  198. hdr.bfType = BFT_BITMAP;
  199. hdr.bfSize = DibSize(lpbi) + sizeof(BITMAPFILEHEADER);
  200. hdr.bfReserved1 = 0;
  201. hdr.bfReserved2 = 0;
  202. hdr.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) + lpbi->biSize + 
  203.  PaletteSize(lpbi);
  204.     /* Write the file header */
  205. _lwrite(fh, (LPSTR) &hdr, sizeof(BITMAPFILEHEADER));
  206.     /* Write the DIB header and the bits */
  207. lwrite(fh, (LPSTR) lpbi, DibSize(lpbi));
  208. _lclose(fh);
  209. return TRUE;
  210. }
  211. PDIB DibOpenFile(LPSTR szFile)
  212. {
  213.  HFILE               fh;
  214.  DWORD               dwLen;
  215.  DWORD               dwBits;
  216.  PDIB                pdib;
  217.  LPVOID              p;
  218.  OFSTRUCT            of;
  219. #if defined(WIN32) || defined(_WIN32)
  220.  #define GetCurrentInstance()    GetModuleHandle(NULL)
  221. #else
  222.  #define GetCurrentInstance()    (HINSTANCE)SELECTOROF((LPVOID)&of)
  223. #endif
  224.  fh = OpenFile(szFile, &of, OF_READ);
  225. #if 0
  226.  if (fh == -1)
  227.  {
  228.   HRSRC h;
  229.   h = FindResource(GetCurrentInstance(), szFile, RT_BITMAP);
  230. #if defined(WIN32) || defined(_WIN32)
  231.   //!!! can we call GlobalFree() on this? is it the right format.
  232.   //!!! can we write to this resource?
  233.   if (h)
  234. return (PDIB)LockResource(LoadResource(GetCurrentInstance(), h));
  235. #else
  236.   if (h)
  237. fh = AccessResource(GetCurrentInstance(), h);
  238. #endif
  239.  }
  240. #endif
  241.  if (fh == -1)
  242.   return NULL;
  243.  pdib = DibReadBitmapInfo(fh);
  244.  if (!pdib)
  245.   return NULL;
  246.     /* How much memory do we need to hold the DIB */
  247.     dwBits = pdib->biSizeImage;
  248.     dwLen  = pdib->biSize + DibPaletteSize(pdib) + dwBits;
  249.     /* Can we get more memory? */
  250.  p = GlobalReAllocPtr(pdib,dwLen,0);
  251.     if (!p)
  252.     {
  253.   GlobalFreePtr(pdib);
  254.         pdib = NULL;
  255.     }
  256.     else
  257.     {
  258.         pdib = (PDIB)p;
  259.     }
  260.     if (pdib)
  261.     {
  262.   /* read in the bits */
  263.   _hread(fh, (LPBYTE)pdib + (UINT)pdib->biSize + DibPaletteSize(pdib), dwBits);
  264.     }
  265.     _lclose(fh);
  266.     return pdib;
  267. }
  268. /*
  269.  *  ReadDibBitmapInfo()
  270.  *
  271.  *  Will read a file in DIB format and return a global HANDLE to its
  272.  *  BITMAPINFO.  This function will work with both "old" and "new"
  273.  *  bitmap formats, but will always return a "new" BITMAPINFO.
  274.  */
  275. PDIB DibReadBitmapInfo(HFILE fh)
  276. {
  277.     DWORD     off;
  278.     HANDLE    hbi = NULL;
  279.     int       size;
  280.     int       i;
  281.     int       nNumColors;
  282.     RGBQUAD FAR       *pRgb;
  283.     BITMAPINFOHEADER   bi;
  284.     BITMAPCOREHEADER   bc;
  285.     BITMAPFILEHEADER   bf;
  286.     PDIB               pdib;
  287.     if (fh == -1)
  288.         return NULL;
  289.     off = _llseek(fh,0L,SEEK_CUR);
  290.     if (sizeof(bf) != _lread(fh,(LPSTR)&bf,sizeof(bf)))
  291.         return FALSE;
  292.     /*
  293.      *  do we have a RC HEADER?
  294.      */
  295.     if (bf.bfType != BFT_BITMAP)
  296.     {
  297.         bf.bfOffBits = 0L;
  298.         _llseek(fh,off,SEEK_SET);
  299.     }
  300.     if (sizeof(bi) != _lread(fh,(LPSTR)&bi,sizeof(bi)))
  301.         return FALSE;
  302.     /*
  303.      *  what type of bitmap info is this?
  304.      */
  305.     switch (size = (int)bi.biSize)
  306.     {
  307.         default:
  308.         case sizeof(BITMAPINFOHEADER):
  309.             break;
  310.         case sizeof(BITMAPCOREHEADER):
  311.             bc = *(BITMAPCOREHEADER*)&bi;
  312.             bi.biSize               = sizeof(BITMAPINFOHEADER);
  313.             bi.biWidth              = (DWORD)bc.bcWidth;
  314.             bi.biHeight             = (DWORD)bc.bcHeight;
  315.             bi.biPlanes             =  (UINT)bc.bcPlanes;
  316.             bi.biBitCount           =  (UINT)bc.bcBitCount;
  317.             bi.biCompression        = BI_RGB;
  318.             bi.biSizeImage          = 0;
  319.             bi.biXPelsPerMeter      = 0;
  320.             bi.biYPelsPerMeter      = 0;
  321.             bi.biClrUsed            = 0;
  322.             bi.biClrImportant       = 0;
  323.             _llseek(fh,(LONG)sizeof(BITMAPCOREHEADER)-sizeof(BITMAPINFOHEADER),SEEK_CUR);
  324.             break;
  325.     }
  326.     nNumColors = DibNumColors(&bi);
  327. #if 0
  328.     if (bi.biSizeImage == 0)
  329.         bi.biSizeImage = DibSizeImage(&bi);
  330.     if (bi.biClrUsed == 0)
  331.         bi.biClrUsed = DibNumColors(&bi);
  332. #else
  333.     FixBitmapInfo(&bi);
  334. #endif
  335.     pdib = (PDIB)GlobalAllocPtr(GMEM_MOVEABLE,(LONG)bi.biSize + nNumColors * sizeof(RGBQUAD));
  336.     if (!pdib)
  337.         return NULL;
  338.     *pdib = bi;
  339.     pRgb = DibColors(pdib);
  340.     if (nNumColors)
  341.     {
  342.         if (size == sizeof(BITMAPCOREHEADER))
  343.         {
  344.             /*
  345.              * convert a old color table (3 byte entries) to a new
  346.              * color table (4 byte entries)
  347.              */
  348.             _lread(fh,(LPVOID)pRgb,nNumColors * sizeof(RGBTRIPLE));
  349.             for (i=nNumColors-1; i>=0; i--)
  350.             {
  351.                 RGBQUAD rgb;
  352.                 rgb.rgbRed      = ((RGBTRIPLE FAR *)pRgb)[i].rgbtRed;
  353.                 rgb.rgbBlue     = ((RGBTRIPLE FAR *)pRgb)[i].rgbtBlue;
  354.                 rgb.rgbGreen    = ((RGBTRIPLE FAR *)pRgb)[i].rgbtGreen;
  355.                 rgb.rgbReserved = (BYTE)0;
  356.                 pRgb[i] = rgb;
  357.             }
  358.         }
  359.         else
  360.         {
  361.             _lread(fh,(LPVOID)pRgb,nNumColors * sizeof(RGBQUAD));
  362.         }
  363.     }
  364.     if (bf.bfOffBits != 0L)
  365.         _llseek(fh,off + bf.bfOffBits,SEEK_SET);
  366.     return pdib;
  367. }
  368. /*
  369.  *  DibSetUsage(hdib,hpal,wUsage)
  370.  *
  371.  *  Modifies the color table of the passed DIB for use with the wUsage
  372.  *  parameter specifed.
  373.  *
  374.  *  if wUsage is DIB_PAL_COLORS the DIB color table is set to 0-256
  375.  *  if wUsage is DIB_RGB_COLORS the DIB color table is set to the RGB values
  376.  *      in the passed palette
  377.  */
  378. BOOL DibSetUsage(PDIB pdib, HPALETTE hpal,UINT wUsage)
  379. {
  380.     PALETTEENTRY       ape[256];
  381.     RGBQUAD FAR *      pRgb;
  382.     WORD FAR *         pw;
  383.     int                nColors;
  384.     int                n;
  385.     if (hpal == NULL)
  386.         hpal = (HPALETTE)GetStockObject(DEFAULT_PALETTE);
  387.     if (!pdib)
  388.         return FALSE;
  389.     nColors = DibNumColors(pdib);
  390.     
  391.     if (nColors == 3 && DibCompression(pdib) == BI_BITFIELDS)
  392.         nColors = 0;
  393.     if (nColors > 0)
  394.     {
  395.         pRgb = DibColors(pdib);
  396.         switch (wUsage)
  397.         {
  398.             //
  399.             // Set the DIB color table to palette indexes
  400.             //
  401.             case DIB_PAL_COLORS:
  402.                 for (pw = (WORD FAR*)pRgb,n=0; n<nColors; n++,pw++)
  403.                     *pw = n;
  404.                 break;
  405.             //
  406.             // Set the DIB color table to RGBQUADS
  407.             //
  408.             default:
  409.             case DIB_RGB_COLORS:
  410.                 nColors =  (nColors < 256) ? nColors: 256;
  411.                 GetPaletteEntries(hpal,0,nColors,ape);
  412.                 for (n=0; n<nColors; n++)
  413.                 {
  414.                     pRgb[n].rgbRed      = ape[n].peRed;
  415.                     pRgb[n].rgbGreen    = ape[n].peGreen;
  416.                     pRgb[n].rgbBlue     = ape[n].peBlue;
  417.                     pRgb[n].rgbReserved = 0;
  418.                 }
  419.                 break;
  420.         }
  421.     }
  422.     return TRUE;
  423. }
  424. /*
  425.  *  DibCreate(bits, dx, dy)
  426.  *
  427.  *  Creates a new packed DIB with the given dimensions and the
  428.  *  given number of bits per pixel
  429.  */
  430. PDIB DibCreate(int bits, int dx, int dy)
  431. {
  432.     LPBITMAPINFOHEADER lpbi ;
  433.     DWORD       dwSizeImage;
  434.     int         i;
  435.     DWORD FAR  *pdw;
  436.     dwSizeImage = dy*(DWORD)((dx*bits/8+3)&~3);
  437.     lpbi = (PDIB)GlobalAllocPtr(GHND,sizeof(BITMAPINFOHEADER)+dwSizeImage + 1024);
  438.     if (lpbi == NULL)
  439.         return NULL;
  440.     lpbi->biSize            = sizeof(BITMAPINFOHEADER) ;
  441.     lpbi->biWidth           = dx;
  442.     lpbi->biHeight          = dy;
  443.     lpbi->biPlanes          = 1;
  444.     lpbi->biBitCount        = bits ;
  445.     lpbi->biCompression     = BI_RGB ;
  446.     lpbi->biSizeImage       = dwSizeImage;
  447.     lpbi->biXPelsPerMeter   = 0 ;
  448.     lpbi->biYPelsPerMeter   = 0 ;
  449.     lpbi->biClrUsed         = 0 ;
  450.     lpbi->biClrImportant    = 0 ;
  451.     if (bits == 4)
  452.         lpbi->biClrUsed = 16;
  453.     else if (bits == 8)
  454.         lpbi->biClrUsed = 256;
  455.     pdw = (DWORD FAR *)((LPBYTE)lpbi+(int)lpbi->biSize);
  456.     for (i=0; i<(int)lpbi->biClrUsed/16; i++)
  457.     {
  458.         *pdw++ = 0x00000000;    // 0000  black
  459.         *pdw++ = 0x00800000;    // 0001  dark red
  460.         *pdw++ = 0x00008000;    // 0010  dark green
  461.   *pdw++ = 0x00808000;    // 0011  mustard
  462.         *pdw++ = 0x00000080;    // 0100  dark blue
  463.         *pdw++ = 0x00800080;    // 0101  purple
  464.         *pdw++ = 0x00008080;    // 0110  dark turquoise
  465.         *pdw++ = 0x00C0C0C0;    // 1000  gray
  466.         *pdw++ = 0x00808080;    // 0111  dark gray
  467.         *pdw++ = 0x00FF0000;    // 1001  red
  468.         *pdw++ = 0x0000FF00;    // 1010  green
  469.   *pdw++ = 0x00FFFF00;    // 1011  yellow
  470.         *pdw++ = 0x000000FF;    // 1100  blue
  471.         *pdw++ = 0x00FF00FF;    // 1101  pink (magenta)
  472.         *pdw++ = 0x0000FFFF;    // 1110  cyan
  473.         *pdw++ = 0x00FFFFFF;    // 1111  white
  474.     }
  475.     return (PDIB)lpbi;
  476. }
  477. static void xlatClut8(BYTE FAR *pb, DWORD dwSize, BYTE FAR *xlat)
  478. {
  479.     DWORD dw;
  480. #ifdef __cplusplus
  481.     for (dw = 0; dw < dwSize; dw++, ((BYTE _huge *&)pb)++)
  482. #else
  483.     for (dw = 0; dw < dwSize; dw++, ((BYTE _huge *)pb)++)
  484. #endif
  485.         *pb = xlat[*pb];
  486. }
  487. static void xlatClut4(BYTE FAR *pb, DWORD dwSize, BYTE FAR *xlat)
  488. {
  489.     DWORD dw;
  490. #ifdef __cplusplus
  491.     for (dw = 0; dw < dwSize; dw++, ((BYTE _huge *&)pb)++)
  492. #else
  493.     for (dw = 0; dw < dwSize; dw++, ((BYTE _huge *)pb)++)
  494. #endif
  495.         *pb = (BYTE)(xlat[*pb & 0x0F] | (xlat[(*pb >> 4) & 0x0F] << 4));
  496. }
  497. #define RLE_ESCAPE  0
  498. #define RLE_EOL     0
  499. #define RLE_EOF     1
  500. #define RLE_JMP     2
  501. static void xlatRle8(BYTE FAR *pb, DWORD dwSize, BYTE FAR *xlat)
  502. {
  503.     BYTE    cnt;
  504.     BYTE    b;
  505.     BYTE _huge *prle = pb;
  506.     for(;;)
  507.     {
  508.         cnt = *prle++;
  509.         b   = *prle;
  510.         if (cnt == RLE_ESCAPE)
  511.         {
  512.             prle++;
  513.             switch (b)
  514.             {
  515.                 case RLE_EOF:
  516.                     return;
  517.                 case RLE_EOL:
  518.                     break;
  519.                 case RLE_JMP:
  520.                     prle++;     // skip dX
  521.                     prle++;     // skip dY
  522.                     break;
  523.                 default:
  524.                     cnt = b;
  525.                     for (b=0; b<cnt; b++,prle++)
  526.                         *prle = xlat[*prle];
  527.                     if (cnt & 1)
  528.                         prle++;
  529.                     break;
  530.             }
  531.         }
  532.         else
  533.         {
  534.             *prle++ = xlat[b];
  535.         }
  536.     }
  537. }
  538. static void xlatRle4(BYTE FAR *pb, DWORD dwSize, BYTE FAR *xlat)
  539. {
  540. }
  541. static void hmemmove(BYTE _huge *d, BYTE _huge *s, LONG len)
  542. {
  543.     d += len-1;
  544.     s += len-1;
  545.     while (len--)
  546.         *d-- = *s--;
  547. }
  548. /*
  549.  *  DibMapToPalette(pdib, hpal)
  550.  *
  551.  *  Map the colors of the DIB, using GetNearestPaletteIndex, to
  552.  *  the colors of the given palette.
  553.  */
  554. BOOL DibMapToPalette(PDIB pdib, HPALETTE hpal)
  555. {
  556.  LPBITMAPINFOHEADER  lpbi;
  557.  PALETTEENTRY        pe;
  558.  int                 n;
  559.  int                 nDibColors;
  560.  int                 nPalColors=0;
  561.  BYTE FAR *          lpBits;
  562.  RGBQUAD FAR *       lpRgb;
  563.  BYTE                xlat[256];
  564.  DWORD               SizeImage;
  565.  if (!hpal || !pdib)
  566.   return FALSE;
  567.  lpbi   = (LPBITMAPINFOHEADER)pdib;
  568.  lpRgb  = DibColors(pdib);
  569.  GetObject(hpal,sizeof(int),(LPSTR)&nPalColors);
  570.  nDibColors = DibNumColors(pdib);
  571.  if ((SizeImage = lpbi->biSizeImage) == 0)
  572.   SizeImage = DibSizeImage(lpbi);
  573.  //
  574.  //  build a xlat table. from the current DIB colors to the given
  575.  //  palette.
  576.  //
  577.  for (n=0; n<nDibColors; n++)
  578.   xlat[n] = (BYTE)GetNearestPaletteIndex(hpal,RGB(lpRgb[n].rgbRed,lpRgb[n].rgbGreen,lpRgb[n].rgbBlue));
  579.  lpBits = (LPBYTE)DibPtr(lpbi);
  580.  lpbi->biClrUsed = nPalColors;
  581.  //
  582.  // re-size the DIB
  583.  //
  584.  if (nPalColors > nDibColors)
  585.  {
  586.   GlobalReAllocPtr(lpbi, lpbi->biSize + nPalColors*sizeof(RGBQUAD) + SizeImage, 0);
  587.   hmemmove((BYTE _huge *)DibPtr(lpbi), (BYTE _huge *)lpBits, SizeImage);
  588.   lpBits = (LPBYTE)DibPtr(lpbi);
  589.  }
  590.  else if (nPalColors < nDibColors)
  591.  {
  592.   hmemcpy(DibPtr(lpbi), lpBits, SizeImage);
  593.   GlobalReAllocPtr(lpbi, lpbi->biSize + nPalColors*sizeof(RGBQUAD) + SizeImage, 0);
  594.   lpBits = (LPBYTE)DibPtr(lpbi);
  595.  }
  596.  //
  597.  // translate the DIB bits
  598.  //
  599.  switch (lpbi->biCompression)
  600.  {
  601.   case BI_RLE8:
  602. xlatRle8(lpBits, SizeImage, xlat);
  603. break;
  604.   case BI_RLE4:
  605. xlatRle4(lpBits, SizeImage, xlat);
  606. break;
  607.         case BI_RGB:
  608. if (lpbi->biBitCount == 8)
  609.                 xlatClut8(lpBits, SizeImage, xlat);
  610.             else
  611.                 xlatClut4(lpBits, SizeImage, xlat);
  612.             break;
  613.     }
  614.     //
  615.     //  Now copy the RGBs in the logical palette to the dib color table
  616.     //
  617.     for (n=0; n<nPalColors; n++)
  618.     {
  619.         GetPaletteEntries(hpal,n,1,&pe);
  620.         lpRgb[n].rgbRed      = pe.peRed;
  621.   lpRgb[n].rgbGreen    = pe.peGreen;
  622.   lpRgb[n].rgbBlue     = pe.peBlue;
  623.   lpRgb[n].rgbReserved = (BYTE)0;
  624.  }
  625.  return TRUE;
  626. }
  627. HPALETTE MakePalette(const BITMAPINFO FAR* Info, UINT flags)
  628. {
  629.   HPALETTE hPalette;
  630.   const RGBQUAD far* rgb = Info->bmiColors;
  631.   WORD nColors = Info->bmiHeader.biClrUsed;
  632.   if (nColors) {
  633.  LOGPALETTE* logPal = (LOGPALETTE*)
  634.  new BYTE[sizeof(LOGPALETTE) + (nColors-1)*sizeof(PALETTEENTRY)];
  635.  logPal->palVersion  = 0x300; // Windows 3.0 version
  636.  logPal->palNumEntries = nColors;
  637.  for (short n = 0; n < nColors; n++) {
  638. logPal->palPalEntry[n].peRed   = rgb[n].rgbRed;
  639. logPal->palPalEntry[n].peGreen = rgb[n].rgbGreen;
  640. logPal->palPalEntry[n].peBlue  = rgb[n].rgbBlue;
  641. logPal->palPalEntry[n].peFlags = (BYTE)flags;
  642.  }
  643.  hPalette = ::CreatePalette(logPal);
  644.  delete logPal;
  645.   } else
  646.  hPalette = 0;
  647.   return hPalette;
  648. }