home *** CD-ROM | disk | FTP | other *** search
/ CD-ROM User 1995 January / CDuser6Jan95.iso / WING / DIB.CP_ / DIB.CP
Text File  |  1994-06-24  |  25KB  |  986 lines

  1. /*----------------------------------------------------------------------------*\
  2. |   Routines for dealing with Device independent bitmaps                       |
  3. \*----------------------------------------------------------------------------*/
  4.  
  5. #include <windows.h>
  6. #include <windowsx.h>
  7. #include "dib.hpp"
  8.  
  9. #if defined(WIN32) || defined(_WIN32)
  10.     #include <memory.h>             // for _fmemcpy()
  11.     #define _huge
  12.     #define hmemcpy memcpy
  13. #endif
  14.  
  15. #define BFT_ICON   0x4349   /* 'IC' */
  16. #define BFT_BITMAP 0x4d42   /* 'BM' */
  17. #define BFT_CURSOR 0x5450   /* 'PT' */
  18.  
  19. /* flags for _lseek */
  20. #define  SEEK_CUR 1
  21. #define  SEEK_END 2
  22. #define  SEEK_SET 0
  23.  
  24. /*
  25.  *   Open a DIB file and return a MEMORY DIB, a memory handle containing..
  26.  *
  27.  *   BITMAP INFO    bi
  28.  *   palette data
  29.  *   bits....
  30.  *
  31.  */
  32. PDIB DibOpenFile(LPSTR szFile)
  33. {
  34.     HFILE               fh;
  35.     DWORD               dwLen;
  36.     DWORD               dwBits;
  37.     PDIB                pdib;
  38.     LPVOID              p;
  39.     OFSTRUCT            of;
  40.  
  41. #if defined(WIN32) || defined(_WIN32)
  42.     #define GetCurrentInstance()    GetModuleHandle(NULL)
  43. #else
  44.     #define GetCurrentInstance()    (HINSTANCE)SELECTOROF((LPVOID)&of)
  45. #endif
  46.  
  47.     fh = OpenFile(szFile, &of, OF_READ);
  48.  
  49.     if (fh == -1)
  50.     {
  51.         HRSRC h;
  52.  
  53.         h = FindResource(GetCurrentInstance(), szFile, RT_BITMAP);
  54.  
  55. #if defined(WIN32) || defined(_WIN32)
  56.         //!!! can we call GlobalFree() on this? is it the right format.
  57.         //!!! can we write to this resource?
  58.         if (h)
  59.             return (PDIB)LockResource(LoadResource(GetCurrentInstance(), h));
  60. #else
  61.         if (h)
  62.             fh = AccessResource(GetCurrentInstance(), h);
  63. #endif
  64.     }
  65.  
  66.     if (fh == -1)
  67.         return NULL;
  68.  
  69.     pdib = DibReadBitmapInfo(fh);
  70.  
  71.     if (!pdib)
  72.         return NULL;
  73.  
  74.     /* How much memory do we need to hold the DIB */
  75.  
  76.     dwBits = pdib->biSizeImage;
  77.     dwLen  = pdib->biSize + DibPaletteSize(pdib) + dwBits;
  78.  
  79.     /* Can we get more memory? */
  80.  
  81.     p = GlobalReAllocPtr(pdib,dwLen,0);
  82.  
  83.     if (!p)
  84.     {
  85.         GlobalFreePtr(pdib);
  86.         pdib = NULL;
  87.     }
  88.     else
  89.     {
  90.         pdib = (PDIB)p;
  91.     }
  92.  
  93.     if (pdib)
  94.     {
  95.         /* read in the bits */
  96.         _hread(fh, (LPBYTE)pdib + (UINT)pdib->biSize + DibPaletteSize(pdib), dwBits);
  97.     }
  98.  
  99.     _lclose(fh);
  100.  
  101.     return pdib;
  102. }
  103.  
  104. /*
  105.  *   Write a global handle in CF_DIB format to a file.
  106.  *
  107.  */
  108. BOOL DibWriteFile(PDIB pdib, LPSTR szFile)
  109. {
  110.     BITMAPFILEHEADER    hdr;
  111.     HFILE               fh;
  112.     OFSTRUCT            of;
  113.     DWORD               dwSize;
  114.  
  115.     if (!pdib)
  116.         return FALSE;
  117.  
  118.     fh = OpenFile(szFile,&of,OF_CREATE|OF_READWRITE);
  119.  
  120.     if (fh == -1)
  121.         return FALSE;
  122.  
  123.     dwSize = DibSize(pdib);
  124.  
  125.     hdr.bfType          = BFT_BITMAP;
  126.     hdr.bfSize          = dwSize + sizeof(BITMAPFILEHEADER);
  127.     hdr.bfReserved1     = 0;
  128.     hdr.bfReserved2     = 0;
  129.     hdr.bfOffBits       = (DWORD)sizeof(BITMAPFILEHEADER) + pdib->biSize +
  130.                           DibPaletteSize(pdib);
  131.  
  132.     _lwrite(fh,(LPCSTR)(LPVOID)&hdr,sizeof(BITMAPFILEHEADER));
  133.     _hwrite(fh,(LPCSTR)(LPVOID)pdib,dwSize);
  134.  
  135.     _lclose(fh);
  136.  
  137.     return TRUE;
  138. }
  139.  
  140. /*
  141.  *  CreateBIPalette()
  142.  *
  143.  *  Given a Pointer to a BITMAPINFO struct will create a
  144.  *  a GDI palette object from the color table.
  145.  *
  146.  */
  147. HPALETTE DibCreatePalette(PDIB pdib)
  148. {
  149.     LOGPALETTE         *pPal;
  150.     HPALETTE            hpal = NULL;
  151.     int                 nNumColors;
  152.     int                 i;
  153.     RGBQUAD FAR *       pRgb;
  154.  
  155.     if (!pdib)
  156.         return NULL;
  157.  
  158.     nNumColors = DibNumColors(pdib);
  159.     
  160.     if (nNumColors == 3 && DibCompression(pdib) == BI_BITFIELDS)
  161.         nNumColors = 0;
  162.  
  163.     if (nNumColors > 0)
  164.     {
  165.         pRgb = DibColors(pdib);
  166.         pPal = (LOGPALETTE*)LocalAlloc(LPTR,sizeof(LOGPALETTE) + nNumColors * sizeof(PALETTEENTRY));
  167.  
  168.         if (!pPal)
  169.             goto exit;
  170.  
  171.         pPal->palNumEntries = nNumColors;
  172.         pPal->palVersion    = 0x300;
  173.  
  174.         for (i = 0; i < nNumColors; i++)
  175.         {
  176.             pPal->palPalEntry[i].peRed   = pRgb->rgbRed;
  177.             pPal->palPalEntry[i].peGreen = pRgb->rgbGreen;
  178.             pPal->palPalEntry[i].peBlue  = pRgb->rgbBlue;
  179.             pPal->palPalEntry[i].peFlags = (BYTE)0;
  180.  
  181.             pRgb++;
  182.         }
  183.  
  184.         hpal = CreatePalette(pPal);
  185.         LocalFree((HLOCAL)pPal);
  186.     }
  187.     else
  188.     {
  189. #if defined(WIN32) || defined(_WIN32)                 
  190.         HDC hdc = GetDC(NULL);
  191.         hpal = CreateHalftonePalette(hdc);      
  192.         ReleaseDC(NULL, hdc);
  193. #endif          
  194.     }
  195.  
  196. exit:
  197.     return hpal;
  198. }
  199.  
  200. /*
  201.  *  ReadDibBitmapInfo()
  202.  *
  203.  *  Will read a file in DIB format and return a global HANDLE to it's
  204.  *  BITMAPINFO.  This function will work with both "old" and "new"
  205.  *  bitmap formats, but will allways return a "new" BITMAPINFO
  206.  *
  207.  */
  208. PDIB DibReadBitmapInfo(HFILE fh)
  209. {
  210.     DWORD     off;
  211.     HANDLE    hbi = NULL;
  212.     int       size;
  213.     int       i;
  214.     int       nNumColors;
  215.  
  216.     RGBQUAD FAR       *pRgb;
  217.     BITMAPINFOHEADER   bi;
  218.     BITMAPCOREHEADER   bc;
  219.     BITMAPFILEHEADER   bf;
  220.     PDIB               pdib;
  221.  
  222.     if (fh == -1)
  223.         return NULL;
  224.  
  225.     off = _llseek(fh,0L,SEEK_CUR);
  226.  
  227.     if (sizeof(bf) != _lread(fh,(LPSTR)&bf,sizeof(bf)))
  228.         return FALSE;
  229.  
  230.     /*
  231.      *  do we have a RC HEADER?
  232.      */
  233.     if (bf.bfType != BFT_BITMAP)
  234.     {
  235.         bf.bfOffBits = 0L;
  236.         _llseek(fh,off,SEEK_SET);
  237.     }
  238.  
  239.     if (sizeof(bi) != _lread(fh,(LPSTR)&bi,sizeof(bi)))
  240.         return FALSE;
  241.  
  242.     /*
  243.      *  what type of bitmap info is this?
  244.      */
  245.     switch (size = (int)bi.biSize)
  246.     {
  247.         default:
  248.         case sizeof(BITMAPINFOHEADER):
  249.             break;
  250.  
  251.         case sizeof(BITMAPCOREHEADER):
  252.             bc = *(BITMAPCOREHEADER*)&bi;
  253.             bi.biSize               = sizeof(BITMAPINFOHEADER);
  254.             bi.biWidth              = (DWORD)bc.bcWidth;
  255.             bi.biHeight             = (DWORD)bc.bcHeight;
  256.             bi.biPlanes             =  (UINT)bc.bcPlanes;
  257.             bi.biBitCount           =  (UINT)bc.bcBitCount;
  258.             bi.biCompression        = BI_RGB;
  259.             bi.biSizeImage          = 0;
  260.             bi.biXPelsPerMeter      = 0;
  261.             bi.biYPelsPerMeter      = 0;
  262.             bi.biClrUsed            = 0;
  263.             bi.biClrImportant       = 0;
  264.  
  265.             _llseek(fh,(LONG)sizeof(BITMAPCOREHEADER)-sizeof(BITMAPINFOHEADER),SEEK_CUR);
  266.  
  267.             break;
  268.     }
  269.  
  270.     nNumColors = DibNumColors(&bi);
  271.  
  272. #if 0
  273.     if (bi.biSizeImage == 0)
  274.         bi.biSizeImage = DibSizeImage(&bi);
  275.  
  276.     if (bi.biClrUsed == 0)
  277.         bi.biClrUsed = DibNumColors(&bi);
  278. #else
  279.     FixBitmapInfo(&bi);
  280. #endif
  281.  
  282.     pdib = (PDIB)GlobalAllocPtr(GMEM_MOVEABLE,(LONG)bi.biSize + nNumColors * sizeof(RGBQUAD));
  283.  
  284.     if (!pdib)
  285.         return NULL;
  286.  
  287.     *pdib = bi;
  288.  
  289.     pRgb = DibColors(pdib);
  290.  
  291.     if (nNumColors)
  292.     {
  293.         if (size == sizeof(BITMAPCOREHEADER))
  294.         {
  295.             /*
  296.              * convert a old color table (3 byte entries) to a new
  297.              * color table (4 byte entries)
  298.              */
  299.             _lread(fh,(LPVOID)pRgb,nNumColors * sizeof(RGBTRIPLE));
  300.  
  301.             for (i=nNumColors-1; i>=0; i--)
  302.             {
  303.                 RGBQUAD rgb;
  304.  
  305.                 rgb.rgbRed      = ((RGBTRIPLE FAR *)pRgb)[i].rgbtRed;
  306.                 rgb.rgbBlue     = ((RGBTRIPLE FAR *)pRgb)[i].rgbtBlue;
  307.                 rgb.rgbGreen    = ((RGBTRIPLE FAR *)pRgb)[i].rgbtGreen;
  308.                 rgb.rgbReserved = (BYTE)0;
  309.  
  310.                 pRgb[i] = rgb;
  311.             }
  312.         }
  313.         else
  314.         {
  315.             _lread(fh,(LPVOID)pRgb,nNumColors * sizeof(RGBQUAD));
  316.         }
  317.     }
  318.  
  319.     if (bf.bfOffBits != 0L)
  320.         _llseek(fh,off + bf.bfOffBits,SEEK_SET);
  321.  
  322.     return pdib;
  323. }
  324.  
  325. /*
  326.  *  DibFromBitmap()
  327.  *
  328.  *  Will create a global memory block in DIB format that represents the DDB
  329.  *  passed in
  330.  *
  331.  */
  332. PDIB DibFromBitmap(HBITMAP hbm, DWORD biStyle, UINT biBits, HPA