home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 2001 June / VPR0106A.BIN / OLS / TCL228 / TCL228.lzh / DLLSRC.lzh / bmp.c next >
C/C++ Source or Header  |  1999-09-18  |  3KB  |  130 lines

  1. /*-----------------------------------------------------
  2.  BMP.C
  3.   ビットマップの読み込み
  4.   KAZUBON 1997
  5. -------------------------------------------------------*/
  6.  
  7. #include "tcdll.h"
  8.  
  9. // 参考:Charls Petzold 「プログラミング Windows3.1」
  10.  
  11. /*--------------------------------------------------
  12.  ビットマップのパレットの数を得る
  13. ----------------------------------------------------*/
  14. int GetDibNumColors(LPBITMAPINFOHEADER pbmih)
  15. {
  16.     int numColors;
  17.     int BitCount;
  18.     
  19.     BitCount = (int)pbmih->biBitCount;
  20.     numColors = (int)pbmih->biClrUsed;
  21.     if(numColors == 0)
  22.     {
  23.         if(BitCount <= 8) numColors = 1 << BitCount;
  24.         else numColors = 0;
  25.     }
  26.     return numColors;
  27. }
  28.  
  29. /*--------------------------------------------------
  30.  ビットマップビットのアドレスを得る
  31. ----------------------------------------------------*/
  32. BYTE* GetDibBitsAddr(BYTE* pDib)
  33. {
  34.     int numColors;
  35.     
  36.     numColors = GetDibNumColors((LPBITMAPINFOHEADER)pDib);
  37.     return pDib + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * numColors;
  38. }
  39.  
  40. /*--------------------------------------------------
  41.  ビットマップの読み込み
  42.  LoadImageと同じことを自力で行う
  43. ----------------------------------------------------*/
  44. HBITMAP ReadBitmap(HWND hwnd, char* fname, BOOL b)
  45. {
  46.     BITMAPFILEHEADER bmfh;
  47.     BYTE* pDib;
  48.     DWORD size;
  49.     HFILE hf;
  50.     BITMAPINFOHEADER* pbmih;
  51.     BYTE* pDIBits;
  52.     HDC hdc;
  53.     BYTE index;
  54.     HBITMAP hBmp;
  55.  
  56.     hf = _lopen(fname, OF_READ);
  57.     if(hf == HFILE_ERROR) return NULL;
  58.     
  59.     size = _llseek(hf, 0, 2) - sizeof(BITMAPFILEHEADER);
  60.     _llseek(hf, 0, 0);
  61.     
  62.     if(_lread(hf, (LPSTR)&bmfh, sizeof(BITMAPFILEHEADER)) !=
  63.         sizeof(BITMAPFILEHEADER))
  64.     {
  65.         _lclose(hf); return NULL;
  66.     }
  67.     
  68.     if(bmfh.bfType != *(WORD *)"BM")
  69.     {
  70.         _lclose(hf); return NULL;
  71.     }
  72.     
  73.     pDib = GlobalAllocPtr(GMEM_MOVEABLE,size);
  74.     if(pDib == NULL)
  75.     {
  76.         _lclose (hf); return NULL;
  77.     }
  78.     
  79.     if(_hread(hf, pDib, size) != (long)size)
  80.     {
  81.         _lclose(hf); GlobalFree(pDib);
  82.         return NULL;
  83.     }
  84.     _lclose(hf);
  85.     
  86.     pbmih = (BITMAPINFOHEADER*)pDib;
  87.     // OS/2形式には対応しない
  88.     if(pbmih->biSize != sizeof(BITMAPINFOHEADER))
  89.     {
  90.         GlobalFree(pDib); return NULL;
  91.     }
  92.     // RLE圧縮には対応しない
  93.     if(pbmih->biCompression != BI_RGB &&
  94.         pbmih->biCompression != BI_BITFIELDS)
  95.     {
  96.         GlobalFree(pDib); return NULL;
  97.     }
  98.     
  99.     if(pbmih->biCompression == BI_RGB)
  100.         pDIBits = GetDibBitsAddr(pDib);
  101.     else
  102.         pDIBits = pDib + sizeof(BITMAPINFOHEADER) + 3 * sizeof(DWORD);
  103.         
  104.     if(b)
  105.     {
  106.         // 最初のドットのパレットを、ボタンの表面の色と同じにする
  107.         if(pbmih->biBitCount == 1)
  108.             index = (*pDIBits & 0x80) >> 7;
  109.         else if(pbmih->biBitCount == 4)
  110.             index = (*pDIBits & 0xF0) >> 4;
  111.         else if(pbmih->biBitCount == 8)
  112.             index = *pDIBits;
  113.         if(pbmih->biBitCount <= 8)
  114.         {
  115.             COLORREF col = GetSysColor(COLOR_3DFACE);
  116.             ((BITMAPINFO*)pDib)->bmiColors[index].rgbBlue = GetBValue(col);
  117.             ((BITMAPINFO*)pDib)->bmiColors[index].rgbGreen = GetGValue(col);
  118.             ((BITMAPINFO*)pDib)->bmiColors[index].rgbRed = GetRValue(col);
  119.         }
  120.     }
  121.     
  122.     hdc = GetDC(hwnd);
  123.     hBmp = CreateDIBitmap(hdc,
  124.         (LPBITMAPINFOHEADER)pDib, CBM_INIT,
  125.         (LPSTR)pDIBits, (LPBITMAPINFO)pDib, DIB_RGB_COLORS);
  126.     ReleaseDC(hwnd, hdc);
  127.     GlobalFree(pDib);
  128.     return hBmp;
  129. }
  130.