⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 win32bitmap.cpp

📁 一个简单漂亮的C++编写的mp3播放器
💻 CPP
字号:
/*____________________________________________________________________________

   FreeAmp - The Free MP3 Player

   Copyright (C) 1999 EMusic

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

   $Id: Win32Bitmap.cpp,v 1.12 2000/01/04 19:07:53 robert Exp $
____________________________________________________________________________*/ 

#include <assert.h>
#include "stdlib.h"
#include "string"
#include "Win32Bitmap.h"
#include "Median.h"
#include "debug.h"

#define DB Debug_v("%s:%d\n", __FILE__, __LINE__);

Win32Bitmap::Win32Bitmap(const string &oName)
            :Bitmap(oName)
{
   m_oBitmapName = oName;
   m_hBitmap = NULL;
   m_hMaskBitmap = NULL;
   m_pBitmapData = NULL;
}

Win32Bitmap::Win32Bitmap(int iWidth, int iHeight, const string &oName)
           :Bitmap(oName)
{
   HDC            hDc;
   BITMAPINFO     sBitmapInfo;

   m_iHeight = iHeight;
   m_iWidth = iWidth;
   m_hMaskBitmap = NULL;

   hDc = GetDC(NULL);
   if (GetDeviceCaps(hDc, RASTERCAPS) & RC_PALETTE)
   {
       m_hBitmap = CreateBitmap(iWidth, iHeight, 1, 8, NULL);
   }
   else
   {
       sBitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 
       sBitmapInfo.bmiHeader.biWidth = iWidth; 
       sBitmapInfo.bmiHeader.biHeight = iHeight; 
       sBitmapInfo.bmiHeader.biPlanes = 1; 
       sBitmapInfo.bmiHeader.biCompression = BI_RGB; 
       sBitmapInfo.bmiHeader.biSizeImage = 0; 
       sBitmapInfo.bmiHeader.biXPelsPerMeter = 0; 
       sBitmapInfo.bmiHeader.biYPelsPerMeter = 0; 
       sBitmapInfo.bmiHeader.biClrUsed = 0; 
       sBitmapInfo.bmiHeader.biClrImportant = 0; 
       sBitmapInfo.bmiHeader.biBitCount = 24;

       m_hBitmap = CreateDIBSection(hDc, &sBitmapInfo, DIB_RGB_COLORS, 
                                    (void **)&m_pBitmapData, NULL, NULL);
   }       
   ReleaseDC(NULL, hDc);
}

Win32Bitmap::~Win32Bitmap(void)
{
   if (m_hBitmap)
   {
       DeleteObject(m_hBitmap);
       m_hBitmap = NULL;
   }
   if (m_hMaskBitmap)
   {
       DeleteObject(m_hMaskBitmap);
       m_hMaskBitmap = NULL;
   }    
}

Error Win32Bitmap::LoadBitmapFromDisk(string &oFile)
{
   DIBSECTION sSection;
   BITMAPINFO sBitmapInfo;
   
   m_hBitmap = (HBITMAP)LoadImage(NULL, oFile.c_str(), IMAGE_BITMAP,
                                  0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
   if (m_hBitmap == NULL)
           return kError_LoadBitmapFailed;

   GetObject(m_hBitmap, sizeof(DIBSECTION), (LPSTR)&sSection);
   memcpy(&sBitmapInfo, &sSection.dsBmih, sizeof(BITMAPINFOHEADER));
   
   m_iHeight = sBitmapInfo.bmiHeader.biHeight;
   m_iWidth = sBitmapInfo.bmiHeader.biWidth;
   m_pBitmapData = sSection.dsBm.bmBits;

   if (m_bHasTransColor)
      CreateMaskBitmap();

   return kError_NoErr;
}

HBITMAP Win32Bitmap::GetBitmapHandle(void)
{
   return m_hBitmap;
}

HBITMAP Win32Bitmap::GetMaskBitmapHandle(void)
{
   return m_hMaskBitmap;
}

void Win32Bitmap::CreateMaskBitmap(void)
{
   BITMAP      sInfo;
   BITMAPINFO *pInfo, *pMaskInfo;
   HDC         hRootDC, hMemDC;
   int         iRet, iLine, iCol;
   char       *pData, *pMaskData;
   Color       sTrans, *pColorPtr;
   COLORREF   *pColorRefPtr;

   hRootDC = GetDC(NULL);
   hMemDC = CreateCompatibleDC(hRootDC);
   ReleaseDC(NULL, hRootDC);

   if (m_hMaskBitmap)
      DeleteObject(m_hMaskBitmap);

   GetObject(m_hBitmap, sizeof(BITMAP), (LPSTR)&sInfo);
   m_hMaskBitmap = CreateBitmap(sInfo.bmWidth, sInfo.bmHeight, 1, 1, NULL);
   
   pInfo = (BITMAPINFO *)new char[sizeof(BITMAPINFOHEADER)];
   pInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
   pInfo->bmiHeader.biWidth = sInfo.bmWidth;
   pInfo->bmiHeader.biHeight = sInfo.bmHeight;
   pInfo->bmiHeader.biPlanes = 1;
   pInfo->bmiHeader.biBitCount = 24;
   pInfo->bmiHeader.biCompression = BI_RGB;
   pInfo->bmiHeader.biSizeImage = 0;
   pInfo->bmiHeader.biXPelsPerMeter = 0;
   pInfo->bmiHeader.biYPelsPerMeter = 0;
   pInfo->bmiHeader.biClrUsed = 0;
   pInfo->bmiHeader.biClrImportant = 0;

   pMaskInfo = (BITMAPINFO *)new char[sizeof(BITMAPINFOHEADER) + 
                                      64 * sizeof(RGBQUAD)];
   pMaskInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
   pMaskInfo->bmiHeader.biWidth = sInfo.bmWidth;
   pMaskInfo->bmiHeader.biHeight = sInfo.bmHeight;
   pMaskInfo->bmiHeader.biPlanes = 1;
   pMaskInfo->bmiHeader.biBitCount = 1;
   pMaskInfo->bmiHeader.biCompression = BI_RGB;
   pMaskInfo->bmiHeader.biSizeImage = 0;
   pMaskInfo->bmiHeader.biXPelsPerMeter = 0;
   pMaskInfo->bmiHeader.biYPelsPerMeter = 0;
   pMaskInfo->bmiHeader.biClrUsed = 2;
   pMaskInfo->bmiHeader.biClrImportant = 0;
   pColorRefPtr = (COLORREF *)(&pMaskInfo->bmiColors);
   pColorRefPtr[0] = RGB(255,255,255);
   pColorRefPtr[1] = RGB(0,0,0);

   pData = new char[sInfo.bmWidth * 4];
   pMaskData = new char[(sInfo.bmWidth / 8) + 4];
   for(iLine = 0; iLine < sInfo.bmHeight; iLine++)
   {
       iRet = GetDIBits(hMemDC, m_hBitmap, 
                        (sInfo.bmHeight - 1) - iLine, 1, 
                        pData, pInfo, DIB_RGB_COLORS);
       if (!iRet)
       {
          break;
       }   

       memset(pMaskData, 0x00, (sInfo.bmWidth / 8) + 4);
   	   for(iCol = 0, pColorPtr = (Color *)pData; 
           iCol < sInfo.bmWidth; iCol++, pColorPtr++)
       {    
   		  if (pColorPtr->red != m_oTransColor.blue ||
   		      pColorPtr->green != m_oTransColor.green ||
   		      pColorPtr->blue != m_oTransColor.red)
          {
             pMaskData[iCol / 8] |= (0x80 >> (iCol % 8));
          }   
       }      
             
       iRet = SetDIBits(hMemDC, m_hMaskBitmap, 
                        (sInfo.bmHeight - 1) - iLine, 1, 
                        pMaskData, pMaskInfo, DIB_RGB_COLORS);
       if (!iRet)
       {
          break;
       }   
   }

   delete pData;
   delete pMaskData;
   delete pInfo;
   delete pMaskInfo;
   DeleteDC(hMemDC);
}

bool Win32Bitmap::IsPosVisible(Pos &oPos)
{
   HDC      hRootDC, hMemDC;
   COLORREF sColor;
   HBITMAP  hSaved;

   if (!m_hMaskBitmap)
      return true;

   hRootDC = GetDC(NULL);
   hMemDC = CreateCompatibleDC(hRootDC);
   ReleaseDC(NULL, hRootDC);

   hSaved = (HBITMAP)SelectObject(hMemDC, m_hMaskBitmap);
   sColor = GetPixel(hMemDC, oPos.x, oPos.y);
   SelectObject(hMemDC, hSaved);
   DeleteDC(hMemDC);
   
   return sColor == 0;
}

Error Win32Bitmap::BlitRect(Bitmap *pOther, Rect &oSrcRect, 
                            Rect &oDestRect)
{
   HDC hRootDC, hSrcDC, hDestDC;
   Win32Bitmap *pSrcBitmap = (Win32Bitmap *)pOther;
 
   if (pSrcBitmap->m_hBitmap == NULL)
      return kError_UnknownErr;

   hRootDC = GetDC(NULL);
   hSrcDC = CreateCompatibleDC(hRootDC);
   hDestDC = CreateCompatibleDC(hRootDC);
   ReleaseDC(NULL, hRootDC);
   
   DeleteObject(SelectObject(hSrcDC, pSrcBitmap->m_hBitmap));
   DeleteObject(SelectObject(hDestDC, m_hBitmap));

//   if (m_hPal)
//   {
//      SelectPalette(hDestDC, m_hPal, false);
//      SelectPalette(hSrcDC, m_hPal, false);
//   }   

   BitBlt(hDestDC, oDestRect.x1, oDestRect.y1, 
                 oDestRect.Width(), oDestRect.Height(),
                 hSrcDC, oSrcRect.x1, oSrcRect.y1, SRCCOPY);
   
   DeleteDC(hSrcDC);
   DeleteDC(hDestDC);

   return kError_NoErr;
}

Error Win32Bitmap::MaskBlitRect(Bitmap *pOther, Rect &oSrcRect, 
                                Rect &oDestRect)
{
   HDC hRootDC, hSrcDC, hDestDC, hMaskDC;
   Win32Bitmap *pSrcBitmap = (Win32Bitmap *)pOther;

   if (!pSrcBitmap->m_hMaskBitmap)
   	  return BlitRect(pOther, oSrcRect, oDestRect);
   
   if (pSrcBitmap->m_hBitmap == NULL)
      return kError_UnknownErr;
   
   hRootDC = GetDC(NULL);
   hSrcDC = CreateCompatibleDC(hRootDC);
   hDestDC = CreateCompatibleDC(hRootDC);
   hMaskDC = CreateCompatibleDC(hRootDC);
   ReleaseDC(NULL, hRootDC);
   
   SelectObject(hSrcDC, pSrcBitmap->m_hBitmap);
   SelectObject(hMaskDC, pSrcBitmap->m_hMaskBitmap);
   SelectObject(hDestDC, m_hBitmap);

   SetBkColor(hSrcDC, RGB(m_oTransColor.red,m_oTransColor.green,m_oTransColor.blue));
   BitBlt(hDestDC, oDestRect.x1, oDestRect.y1, 
                   oDestRect.Width(), oDestRect.Height(),
          hSrcDC, oSrcRect.x1, oSrcRect.y1, SRCINVERT);
   BitBlt(hDestDC, oDestRect.x1, oDestRect.y1, 
                   oDestRect.Width(), oDestRect.Height(),
          hMaskDC, oSrcRect.x1, oSrcRect.y1, SRCAND);
   BitBlt(hDestDC, oDestRect.x1, oDestRect.y1, 
                   oDestRect.Width(), oDestRect.Height(),
          hSrcDC, oSrcRect.x1, oSrcRect.y1, SRCINVERT);

   DeleteDC(hSrcDC);
   DeleteDC(hDestDC);
   DeleteDC(hMaskDC);

   return kError_NoErr;
}

void Win32Bitmap::UpdateHistogram(WORD *pHist)
{
   BITMAP      sInfo;
   BITMAPINFO *pInfo;
   HDC         hRootDC, hMemDC;
   int         iRet, iLine, iCol;
   char       *pData;
   Color       sTrans, *pColorPtr;

   hRootDC = GetDC(NULL);
   hMemDC = CreateCompatibleDC(hRootDC);
   ReleaseDC(NULL, hRootDC);

   GetObject(m_hBitmap, sizeof(BITMAP), (LPSTR)&sInfo);
   
   pInfo = (BITMAPINFO *)new char[sizeof(BITMAPINFOHEADER)];
   pInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
   pInfo->bmiHeader.biWidth = sInfo.bmWidth;
   pInfo->bmiHeader.biHeight = sInfo.bmHeight;
   pInfo->bmiHeader.biPlanes = 1;
   pInfo->bmiHeader.biBitCount = 24;
   pInfo->bmiHeader.biCompression = BI_RGB;
   pInfo->bmiHeader.biSizeImage = 0;
   pInfo->bmiHeader.biXPelsPerMeter = 0;
   pInfo->bmiHeader.biYPelsPerMeter = 0;
   pInfo->bmiHeader.biClrUsed = 0;
   pInfo->bmiHeader.biClrImportant = 0;

   pData = new char[sInfo.bmWidth * 4];
   for(iLine = 0; iLine < sInfo.bmHeight; iLine++)
   {
       iRet = GetDIBits(hMemDC, m_hBitmap, 
                        (sInfo.bmHeight - 1) - iLine, 1, 
                        pData, pInfo, DIB_RGB_COLORS);
       if (!iRet)
       {
          break;
       }   

   	   for(iCol = 0, pColorPtr = (Color *)pData; 
           iCol < sInfo.bmWidth; iCol++, pColorPtr++)
       {    
   		  if (pColorPtr->red != m_oTransColor.blue ||
   		      pColorPtr->green != m_oTransColor.green ||
   		      pColorPtr->blue != m_oTransColor.red)
               pHist[mcRGB(pColorPtr->blue, pColorPtr->green, pColorPtr->red)]++;
              
       }      
   }

   delete pData;
   delete pInfo;
   DeleteDC(hMemDC);
}

void Win32Bitmap::ConvertTo256Color(WORD            *pHist,
                                    RGBQUAD         *pColorTable)
{
   BITMAP         sInfo;
   BITMAPINFO    *pInfo;
   HDC            hRootDC, hMemDC;
   int            iRet, iLine, iCol, iPack;
   unsigned char *pData, *p8BitData, *pDest;
   Color          sTrans, *pColorPtr;
   HBITMAP        h8BitBitmap;
               
   hRootDC = GetDC(NULL);
   hMemDC = CreateCompatibleDC(hRootDC);
   ReleaseDC(NULL, hRootDC);

   GetObject(m_hBitmap, sizeof(BITMAP), (LPSTR)&sInfo);
   
   pInfo = (BITMAPINFO *)new char[sizeof(BITMAPINFOHEADER)];
   pInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
   pInfo->bmiHeader.biWidth = sInfo.bmWidth;
   pInfo->bmiHeader.biHeight = sInfo.bmHeight;
   pInfo->bmiHeader.biPlanes = 1;
   pInfo->bmiHeader.biBitCount = 24;
   pInfo->bmiHeader.biCompression = BI_RGB;
   pInfo->bmiHeader.biSizeImage = 0;
   pInfo->bmiHeader.biXPelsPerMeter = 0;
   pInfo->bmiHeader.biYPelsPerMeter = 0;
   pInfo->bmiHeader.biClrUsed = 0;
   pInfo->bmiHeader.biClrImportant = 0;

   iPack = sInfo.bmWidth % 2; 
   
   pData = new unsigned char[sInfo.bmWidth * 4];
   p8BitData = new unsigned char[(sInfo.bmWidth + iPack) * sInfo.bmHeight];
   for(iLine = 0, pDest = p8BitData; iLine < sInfo.bmHeight; iLine++)
   {
       iRet = GetDIBits(hMemDC, m_hBitmap, 
                        (sInfo.bmHeight - 1) - iLine, 1, 
                        pData, pInfo, DIB_RGB_COLORS);
       if (!iRet)
       {
          break;
       }   

   	   for(iCol = 0, pColorPtr = (Color *)pData; 
           iCol < sInfo.bmWidth; iCol++, pColorPtr++, pDest++)
       {
          *pDest = pHist[mcRGB(pColorPtr->blue, pColorPtr->green, pColorPtr->red)] + 10;
       }
       pDest += iPack;
   }

   h8BitBitmap = CreateBitmap(sInfo.bmWidth, sInfo.bmHeight, 1, 8, p8BitData);
   
   delete pData;
   delete p8BitData;
   delete pInfo;
   DeleteDC(hMemDC);

   if (m_hBitmap)
   {
      DeleteObject(m_hBitmap);
      m_pBitmapData = NULL;
   }
      
   m_hBitmap = h8BitBitmap;
   m_pBitmapData = NULL;
}

void Win32Bitmap::SetPalette(HPALETTE hPal)
{
   if (m_hPal)
       DeleteObject(m_hPal);
       
   m_hPal = hPal;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -