home *** CD-ROM | disk | FTP | other *** search
/ CD-ROM User 1995 January / CDuser6Jan95.iso / WING / DIB.C_ / DIB.C
C/C++ Source or Header  |  1994-06-19  |  25KB  |  998 lines

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