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

📄 bvcdib.cpp

📁 BCAM 1394 Driver
💻 CPP
字号:
//-----------------------------------------------------------------------------
//  (c) 2002 by Basler Vision Technologies
//  Section:  Vision Components
//  Project:  BVC
//  $Header: BvcDib.cpp, 6, 12.04.2005 18:46:53, Nebelung, H.$
//-----------------------------------------------------------------------------
/**
  \file     BvcDib.cpp
 *
  \brief   <type brief description here>
 *
 * <type long description here>
 */
//-----------------------------------------------------------------------------


#include "stdafx.h"
#include "BvcDib.h"
#include <assert.h>
#include "dibsectn.h"

/*! \def IPL_SUPPORT
If this symbol is defined CDib supports IPL's (= Intel Performance Library)
native image format IplImage.
*/
#ifdef IPL_SUPPORT
#include <ipl.h>
#endif

using namespace Bvc;

//! Default constructor
CDib::CDib() :
m_hBitmap(NULL),
m_Orientation(BottomUp),
m_PaletteType(Color),
m_RefCount(0)
{
#ifdef IPL_SUPPORT
  m_pIplImage = NULL;
#endif
}

//! Destroy all BMP related resources 
void CDib::Destroy() 
{
  // Destroy the referenced DIB section
  if(m_hBitmap)
  {
    if(!::DeleteObject(m_hBitmap))
      throw  BvcException( ::GetLastError(), _T( "CDib::Destroy" ));
    m_hBitmap = NULL;
  }
  
#ifdef IPL_SUPPORT
  
  // Destroy the IPL image header
  if(m_pIplImage)
  {
    iplDeallocate( m_pIplImage, IPL_IMAGE_HEADER );
    m_pIplImage = NULL;
  }
  
#endif // #ifdef IPL_SUPPORT
  
}

//! Increments the reference counter of this object
long CDib::AddRef()
{
  return ::InterlockedIncrement(&m_RefCount);
}

//! Decrements the reference counter of this object. Destroys the object if the reference counter becomes 0.
void CDib::Release()
{
  ::InterlockedDecrement(&m_RefCount);
  if(0 == m_RefCount)
    delete this;
}

//! Create a CDib object
CDib* CDib::Create( CSize Size, unsigned int BitsPerPixel, Orientation_t Orientation, PaletteType_t PaletteType ) 
{
  CDib *pDib = new CDib();
  
  pDib->m_Orientation = Orientation;
  pDib->m_PaletteType = PaletteType;
  
  pDib->m_hBitmap = DSCreateDIBSection( Size.cx, Orientation == BottomUp ? Size.cy : -Size.cy, WORD( BitsPerPixel ), PaletteType == Monochrome );
  if(!pDib->m_hBitmap)
    throw  BvcException( Bvc::ErrorNumber( E_FAIL ), _T( "CDib::Create" ) );
  
  pDib->AddRef();
  
  pDib->Refresh();
  
  return  pDib;
}

//!  Loads the bitmap from a BMP file
CDib* CDib::LoadBMP( CString FileName )
{
  CDib *pDib = new CDib();
  
  if(!DSLoadDIBSectionFromBMPFile( (LPCTSTR) FileName, &pDib->m_hBitmap, NULL ))
    throw  BvcException( Bvc::ErrorNumber( E_FAIL ), _T( "CDib::LoadBMP" ) );
  
  // BMP files are always bottom up
  pDib->m_Orientation = BottomUp;
  
  // Check if the image is Mono8
  pDib->m_PaletteType = Color;
  LPBITMAPINFO pBitmapInfo = DSGetBITMAPINFOForDIBSection( pDib->m_hBitmap );
  if(pBitmapInfo->bmiHeader.biBitCount == 8)
  {
    for(int i=0; i<256; ++i)
    {
      if(    pBitmapInfo->bmiColors[i].rgbRed != i
        || pBitmapInfo->bmiColors[i].rgbGreen != i
        || pBitmapInfo->bmiColors[i].rgbBlue != i )
        break;
    }
    pDib->m_PaletteType = Monochrome;
  }
  
  free(pBitmapInfo);
  
  pDib->AddRef();
  
  pDib->Refresh();
  
  return pDib;
}

//! Virtual destructor
CDib::~CDib() 
{
  Destroy();
}

//! checks if twobitmaps share the same properties
bool CDib::IsEqualType( const CDib& Dib ) const
{
  BITMAP ThisBitmap;
  BITMAP Bitmap;
  GetBitmap(&ThisBitmap); 
  Dib.GetBitmap(&Bitmap); 
  return(    Bitmap.bmType == ThisBitmap.bmType
    && Bitmap.bmWidth == ThisBitmap.bmWidth
    && Bitmap.bmHeight == ThisBitmap.bmHeight
    && Bitmap.bmWidthBytes == ThisBitmap.bmWidthBytes
    && Bitmap.bmPlanes == ThisBitmap.bmPlanes
    && Bitmap.bmBitsPixel == ThisBitmap.bmBitsPixel
    && Dib.m_Orientation == m_Orientation ); 
}

//!  Stores the bitmap to a BMP file
void CDib::StoreBMP( CString FileName ) const
{
  if( m_Orientation == TopDown )
  {
    // BMP file have to be stores bottom up so we have to topple it
    HBITMAP hBitmap = GetToppledCopy();
    DSStoreDIBSectionInBMPFile( (LPCTSTR) FileName, hBitmap);
    ::DeleteObject(hBitmap);
  }
  else
  {
    DSStoreDIBSectionInBMPFile( (LPCTSTR) FileName, m_hBitmap);
  }
}

//! Gets a HBITMAP handle (no ownership is granted!)
HBITMAP CDib::GetBitmapHandle() const
{ 
  return m_hBitmap; 
}

//!  Returns a pointer to the pixel data 
void* CDib::GetPixels() const
{
  BITMAP Bitmap;
  if(!::GetObject(m_hBitmap, sizeof(BITMAP), &Bitmap))
    throw  BvcException( ::GetLastError(), _T( "CDib::GetPixels" ) );
  
  return Bitmap.bmBits;
}

//!  Returns the bitmap's size 1
void CDib::GetSize(CSize *pSize) const
{
  assert(pSize);
  if(!m_hBitmap)
  {
    pSize->cx = 0;
    pSize->cy = 0;
  }
  else
  {
    BITMAP Bitmap;
    if(!::GetObject(m_hBitmap, sizeof(BITMAP), &Bitmap))
      throw  BvcException( ::GetLastError(), _T( "CDib::GetSize" ) );
    
    pSize->cx = Bitmap.bmWidth;
    pSize->cy = Bitmap.bmHeight;
  }
}

//!  Returns the bitmap's size 2
CSize CDib::GetSize() const
{
  CSize Size;
  GetSize(&Size);
  return Size;
}

//!  Returns the total size of a line in bytes
unsigned long CDib::GetWidthBytes() const
{
  BITMAP Bitmap;
  if(!::GetObject(m_hBitmap, sizeof(BITMAP), &Bitmap))
    throw  BvcException( ::GetLastError(), _T( "CDib::GetSize" ) );
  
  return Bitmap.bmWidthBytes;
}

//!  Returns the total size of the image in bytes
unsigned long CDib::GetTotalPixelBytes() const
{
  BITMAP Bitmap;
  if(!::GetObject(m_hBitmap, sizeof(BITMAP), &Bitmap))
    throw  BvcException( ::GetLastError(), _T( "CDib::GetSize" ) );
  
  return Bitmap.bmWidthBytes * Bitmap.bmHeight;
}

//!  Returns the bitmap's bits per pixel
unsigned short CDib::GetBitsPerPixel() const
{
  BITMAP Bitmap;
  if(!::GetObject(m_hBitmap, sizeof(BITMAP), &Bitmap))
    throw  BvcException( ::GetLastError(), _T( "CDib::GetBitsPerPixel" ) );
  
  return Bitmap.bmBitsPixel;
}

//! Returns the bitmaps orientation (BottomUp or TopDown)
CDib::Orientation_t CDib::GetOrientation() const
{
  return m_Orientation;
}

//! Returns the bitmaps palette type (e.g., color or monochrome )
CDib::PaletteType_t CDib::GetPaletteType() const
{
  return m_PaletteType;
}

//! Returns the bitmaps BITMAPINFORHEADER 
void CDib::GetBitmapInfoHeader(BITMAPINFOHEADER *pBitmapInfoHeader) const
{
  DIBSECTION DibSection;
  if(!::GetObject(m_hBitmap, sizeof(DIBSECTION), &DibSection))
    throw  BvcException( ::GetLastError(), _T( "CDib::GetBitmapInfoHeader" ) );
  
  ::CopyMemory(pBitmapInfoHeader, &(DibSection.dsBmih), sizeof(BITMAPINFOHEADER));
}

//! Returns a bitmaps BITMAPINFO which has to be freed by the user
void CDib::GetBitmapInfo(BITMAPINFO **ppBitmapInfo, unsigned long *pBitmapInfoBytes) const
{
  
  *ppBitmapInfo = DSGetBITMAPINFOForDIBSection( m_hBitmap );
  *pBitmapInfoBytes = sizeof(BITMAPINFOHEADER) + DSColorTableSize( *ppBitmapInfo );
}

//! Returns the bitmaps BITMAP 
void CDib::GetBitmap(BITMAP *pBitmap) const
{
  if(!::GetObject(m_hBitmap, sizeof(BITMAP), pBitmap))
    throw  BvcException( ::GetLastError(), _T( "CDib::GetBitmap" ) );
}

//!  Topples the bitmap
void CDib::Topple()
{
  if (m_hBitmap == NULL)
    throw  BvcException( Bvc::ErrorNumber( E_FAIL ), _T( "CDib::Topple - No bitmap present" ) );
  
  HBITMAP hBitmap = GetToppledCopy();
  Destroy();
  
  m_hBitmap = hBitmap;
  
  m_Orientation = m_Orientation == BottomUp ? TopDown : BottomUp;
  
  Refresh();
  
}

//! Clones the Bitmap 
CDib* CDib::Clone(
                  bool Topple //!< If true the clone will be toppled with resprect to the original bitmap
                  ) const
{
  if (m_hBitmap == NULL)
    throw  BvcException( Bvc::ErrorNumber( E_FAIL ), _T( "CDib::Clone - No bitmap present" ) );
  
  HBITMAP pBitmap = NULL;
  if(Topple)
  {
    pBitmap = GetToppledCopy();
  }
  else
  {
    pBitmap = GetCopy();
  }
  
  CDib *pDib = new CDib();
  pDib->m_hBitmap = pBitmap;
  pDib->m_Orientation = Topple ? (m_Orientation == BottomUp ? TopDown : BottomUp) : m_Orientation;
  pDib->m_PaletteType = m_PaletteType;
  pDib->AddRef();
  
  pDib->Refresh();
  
  return pDib;
}

//! Copies the image to the clipboard
void CDib::CopyToClipboard()
{
  if ( GetOrientation() == CDib::TopDown )
  {
    CDib* pDib = Clone(true);
    if (pDib == NULL)
      throw  BvcException( Bvc::ErrorNumber( E_FAIL ), _T( "CDib::CopyToClipboard" ) );
    pDib->CopyToClipboard();
    delete pDib;
  }
  else
  {
    HGLOBAL hGlobal = NULL;
    try
    {
      if (m_hBitmap == NULL)
        throw  BvcException( Bvc::ErrorNumber( E_FAIL ), _T( "CDib::CopyToClipboard - No bitmap present" ) );
      
      // Get BITMAPINFO Header
      LPBITMAPINFO pBitmapInfo;
      pBitmapInfo = DSGetBITMAPINFOForDIBSection( m_hBitmap );
      if(!pBitmapInfo)
        throw  BvcException( ::GetLastError(), _T( "CDib::CopyToClipboard" ) );
      
      // Create a suitable global memory buffer and lock it 
      DWORD TotalDIBBytes = DSTotalBytesSize( pBitmapInfo );
      hGlobal = GlobalAlloc(GHND | GMEM_SHARE, TotalDIBBytes );
      if(!hGlobal)
        throw  BvcException( ::GetLastError(), _T( "CDib::CopyToClipboard" ) );
      
      // Lock the global Buffer
      char* pBuffer = (char*) GlobalLock(hGlobal);
      if ( pBuffer == NULL )
        throw  BvcException( ::GetLastError(), _T( "CDib::CopyToClipboard" ) );
      
      // Copy the information header and the color table to the global Buffer
      DWORD dwHeaderSize = sizeof(BITMAPINFOHEADER) + DSColorTableSize( pBitmapInfo );
      CopyMemory(pBuffer, &pBitmapInfo->bmiHeader, dwHeaderSize);
      
      // Copy the image data to the global buffer
      LPBYTE pBits = DSGetPointerToDIBSectionImageBits(  m_hBitmap  );
      DWORD dwSize = DSImageBitsSize( pBitmapInfo );
      CopyMemory(((PBYTE) pBuffer) + dwHeaderSize, pBits, dwSize);
      
      // Clean up
      free(pBitmapInfo);
      GlobalUnlock(hGlobal);
      
      // set the buffer to the clipboard
      if(!::OpenClipboard(NULL))
        throw  BvcException( ::GetLastError(), _T( "CDib::CopyToClipboard" ) );
      
      if(!::EmptyClipboard())
        throw  BvcException( ::GetLastError(), _T( "CDib::CopyToClipboard" ) );
      
      if(!::SetClipboardData(CF_DIB, hGlobal))
        throw  BvcException( ::GetLastError(), _T( "CDib::CopyToClipboard" ) );
      
      if(!::CloseClipboard())
        throw  BvcException( ::GetLastError(), _T( "CDib::CopyToClipboard" ) );
    }
    catch(BvcException e)
    {
      if(hGlobal)
        ::GlobalFree(hGlobal);
      throw e;
    }
  }
}


//!  Returns a DIB section which is a copy of the referenced bitmap
HBITMAP CDib::GetCopy() const
{
  if (m_hBitmap == NULL)
    throw  BvcException( Bvc::ErrorNumber( E_FAIL ), _T( "CDib::GetCopy - No bitmap present" ) );
  
  LPBITMAPINFO pBitmap = DSGetBITMAPINFOForDIBSection(m_hBitmap);
  if (! pBitmap) throw BvcException( Bvc::ErrorNumber( E_FAIL ), _T( "CDib::GetCopy - No bitmap info present" ) );
  pBitmap->bmiHeader.biHeight = m_Orientation == TopDown ? -pBitmap->bmiHeader.biHeight : pBitmap->bmiHeader.biHeight;
  
  LPBYTE pSrc = DSGetPointerToDIBSectionImageBits(m_hBitmap);
  if (!pSrc) throw BvcException( ::GetLastError(), _T( "CDib::GetCopy" ) );
  
  LPBYTE pDst = NULL;
  HBITMAP hBitmap = ::CreateDIBSection( NULL, pBitmap, DIB_RGB_COLORS, (void**)&pDst, NULL, 0 );
  const size_t imagesize = pBitmap->bmiHeader.biSizeImage;
  free(pBitmap);
  
  if(hBitmap == NULL || pDst == NULL)
    throw  BvcException( ::GetLastError(), _T( "CDib::GetCopy" ) );

  memcpy( pDst, pSrc, imagesize );
 
  return hBitmap;
}

//!  Returns a DIB section which is a toppled copy of the referenced bitmap
HBITMAP CDib::GetToppledCopy() const
{
  if (m_hBitmap == NULL)
    throw  BvcException( Bvc::ErrorNumber( E_FAIL ), _T( "CDib::GetToppledCopy - No bitmap present" ) );
  
  LPBITMAPINFO pBitmap = DSGetBITMAPINFOForDIBSection(m_hBitmap);
  if (!pBitmap) throw  BvcException( ::GetLastError(), _T( "CDib::GetToppledCopy" ) );

  
  LPBYTE pSrc = DSGetPointerToDIBSectionImageBits(m_hBitmap);
  if (!pSrc) throw  BvcException( ::GetLastError(), _T( "CDib::GetToppledCopy" ) );
  
  // Create a version of the image which is top down if the original image was bottom up 
  // and vice versa. 
  // BEWARE : For some strange reason the newly created image will have a biHeight > 0
  // even if we created it with biHeight < 0. Nevertheless the bitmap object somehow
  // remembers the fact that it is top-down because if it's drawn it appears correct
  pBitmap->bmiHeader.biHeight = -pBitmap->bmiHeader.biHeight;
  
  LPBYTE pDst = NULL;
  HBITMAP hBitmap = ::CreateDIBSection( NULL, pBitmap, DIB_RGB_COLORS, (void**)&pDst, NULL, 0 );
  if(hBitmap == NULL || pDst == NULL)
    throw  BvcException( ::GetLastError(), _T( "CDib::GetToppledCopy" ) );
  
  DWORD rowlength = GetWidthBytes();
  
  for( int i = 0, m = abs(pBitmap->bmiHeader.biHeight) - 1;  i < abs(pBitmap->bmiHeader.biHeight); i++, m-- )
  {
    memcpy(pDst + m * rowlength, pSrc + i * rowlength, rowlength);
  }

  free(pBitmap);

  return hBitmap;
}

//!  This function is called whenever the bitmap is re-created
void CDib::Refresh()
{
  
  // TODO : Create a matching palette (but honestly : who is using
  // palettised graphic cards any more? :-)
  
#ifdef IPL_SUPPORT
  
  // Create a IPL header describing the BMP. No additional memory is allocated
  if( m_hBitmap )
  {
    
    BITMAP Bitmap;
    GetBitmap(&Bitmap);
    
    int nChannels = Bitmap.bmBitsPixel == 1 ? 1 : Bitmap.bmBitsPixel/8;
    int depth     = Bitmap.bmBitsPixel == 1 ? IPL_DEPTH_1U : IPL_DEPTH_8U;
    int origin          = m_Orientation == BottomUp ? IPL_ORIGIN_BL : IPL_ORIGIN_TL;
    
    m_pIplImage = iplCreateImageHeader(
      nChannels,      // number of channels
      0,              // # of alpha channel, 0-absent
      depth,          // bit depth of channel
      "RGB",          // color model
      "BGR",          // channel sequence
      IPL_DATA_ORDER_PIXEL,// data ordering : by pixels or by channels
      origin,             // bitmap origin : _TL = top left, _BL = bottom left
      IPL_ALIGN_DWORD,// scan lines alignment
      Bitmap.bmWidth,    // width in pixels
      Bitmap.bmHeight,   // height and 
      0,              // ROI, 0 - entire image  
      0,              // MASK ROI, 0 - entire image  
      0,              // image ID - reserved
      0);             // tile info.
    
    m_pIplImage->imageData = m_pIplImage->imageDataOrigin = (char*)(Bitmap.bmBits);
  }
  
#endif // #ifdef IPL_SUPPORT
}

⌨️ 快捷键说明

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