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

📄 dibsectn.cpp

📁 BCAM 1394 Driver
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//-----------------------------------------------------------------------------
//  (c) 2002 by Basler Vision Technologies
//  Section: Vision Components
//  Project: BVC
//  $Header: DibSectn.cpp, 2, 25.09.2003 12:36:45, Nebelung, H.$
//-----------------------------------------------------------------------------
/**
  \file     DIBSECTN.CPP
  \brief  Implementaiton for the DIBSections functions

  - Most of the functions in this module which are passed an HBITMAP
  as a parameter assume the HBITMAP is not selected into a device
  context at the time of the call. Since the underlying APIs usually
  require this, so do these functions.
  
  - Throughout this module, code is in place to handle color tables
  in DIBSections (in the BITMAPINFO) even when it is not necessary.
  This helps the re-usability of the code, since it is often desirable
  to include a "suggested" color table when storing 16bpp or higher
  BMP files. 

*/

#include <stdafx.h>
#include <memory.h>
#include <bvcexception.h>
#include "DibSectn.h"

using namespace Bvc;


/*! Macro to determine the number of bytes per line in the DIB bits. This
accounts for DWORD alignment by adding 31 bits, then dividing by 32,
then rounding up to the next highest count of 4-bytes. Then, we 
multiply by 4 to get the total byte count.
*/
#define BYTESPERLINE(Width, BPP) ((WORD)((((DWORD)(Width) * (DWORD)(BPP) + 31) >> 5)) << 2)


/*!
The DIBSection is created with a default color table - for 8bpp and
above, this is a spectrum palette. For 4bpp, it is a stock 16 color
table, and for 1bpp it is black and white.

  \return 
  - HBITMAP       a DIBSection HBITMAP of the desired size and bit-depth
  - NULL          on failure
*/
HBITMAP DSCreateDIBSection( 
                           LONG dwX,               //!< Desired width of the DIBSection
                           LONG dwY,               //!< Desired height of the DIBSection
                           WORD wBits,             //!< Desired bit-depth of the DIBSection
                           BOOL Monochrome //!< If wBits=8 and Monochrome=true the palette will contain grey values only
                           )
{
  HBITMAP         hBitmap;
  LPBYTE          pBits;
  int             nInfoSize;
  LPBITMAPINFO    pbmi;
  HDC             hRefDC;
  
  nInfoSize = sizeof( BITMAPINFOHEADER );
  if( wBits <= 8 )
    nInfoSize += sizeof(RGBQUAD) * (1 << wBits);
  if( ( wBits == 16 ) || ( wBits == 32 ) )
    nInfoSize += 3 * sizeof(DWORD);
  
  // Create the header big enough to contain color table and bitmasks if needed
  pbmi = (LPBITMAPINFO)malloc( nInfoSize );
  ZeroMemory( pbmi, nInfoSize );
  pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  pbmi->bmiHeader.biWidth = dwX;
  pbmi->bmiHeader.biHeight = dwY;
  pbmi->bmiHeader.biPlanes = 1; 
  pbmi->bmiHeader.biBitCount = wBits;
  pbmi->bmiHeader.biCompression = BI_RGB; // override below for 16 and 32bpp
  
  switch( wBits )
  {
  case 24:
    // 24bpp requires no special handling
    break;
    
  case 16:
    {   // if it's 16bpp, fill in the masks and override the compression
      // these are the default masks - you could change them if needed
      LPDWORD pMasks = (LPDWORD)(pbmi->bmiColors);
      pMasks[0] = 0x00007c00;
      pMasks[1] = 0x000003e0;
      pMasks[2] = 0x0000001f;
      pbmi->bmiHeader.biCompression = BI_BITFIELDS;
    }
    break;
    
  case 32:
    {   // if it's 32bpp, fill in the masks and override the compression
      // these are the default masks - you could change them if needed
      LPDWORD pMasks = (LPDWORD)(pbmi->bmiColors);
      pMasks[0] = 0x00ff0000;
      pMasks[1] = 0x0000ff00;
      pMasks[2] = 0x000000ff;
      pbmi->bmiHeader.biCompression = BI_BITFIELDS; 
    }
    break;
    
  case 8:  
    {
      if(Monochrome)
      {
        int             i;
        for(i=0;i<256;i++)
        {
          pbmi->bmiColors[i].rgbRed = BYTE( i );
          pbmi->bmiColors[i].rgbGreen = BYTE( i );
          pbmi->bmiColors[i].rgbBlue = BYTE( i );
          pbmi->bmiColors[i].rgbReserved = BYTE( 0 );
        }
        pbmi->bmiHeader.biClrUsed = 256;
      }
      else // color
      {
        HPALETTE        hPal;
        PALETTEENTRY    pe[256];
        int             i;
        // at this point, prgb points to the color table, even 
        // if bitmasks are present
        hPal = DSCreateSpectrumPalette();
        GetPaletteEntries( hPal, 0, 256, pe );
        for(i=0;i<256;i++)
        {
          pbmi->bmiColors[i].rgbRed = pe[i].peRed;
          pbmi->bmiColors[i].rgbGreen = pe[i].peGreen;
          pbmi->bmiColors[i].rgbBlue = pe[i].peBlue;
          pbmi->bmiColors[i].rgbReserved = 0;
        }
        ::DeleteObject( hPal );
        pbmi->bmiHeader.biClrUsed = 256;
      }
    }
    break;
    
  case 4:
    {   // Use a default 16 color table for 4bpp DIBSections
      RGBTRIPLE       rgb[16] = { { 0x00, 0x00, 0x00 }, // black 
      { 0x80, 0x00, 0x00 }, // dark red 
      { 0x00, 0x80, 0x00 }, // dark green 
      { 0x80, 0x80, 0x00 }, // dark yellow 
      { 0x00, 0x00, 0x80 }, // dark blue 
      { 0x80, 0x00, 0x80 }, // dark magenta 
      { 0x00, 0x80, 0x80 }, // dark cyan 
      { 0xC0, 0xC0, 0xC0 }, // light gray 
      //  { 0xC0, 0xDC, 0xC0 }, // money green 
      //  { 0xA6, 0xCA, 0xF0 }, // sky blue 
      //  { 0xFF, 0xFB, 0xF0 }, // cream 
      //  { 0xA0, 0xA0, 0xA4 }, // light gray 
      { 0x80, 0x80, 0x80 }, // medium gray 
      { 0xFF, 0x00, 0x00 }, // red 
      { 0x00, 0xFF, 0x00 }, // green 
      { 0xFF, 0xFF, 0x00 }, // yellow 
      { 0x00, 0x00, 0xFF }, // blue 
      { 0xFF, 0x00, 0xFF }, // magenta 
      { 0x00, 0xFF, 0xFF }, // cyan 
      { 0xFF, 0xFF, 0xFF } }; // white 
      int i;
      
      for(i=0;i<16;i++)
      {
        pbmi->bmiColors[i].rgbRed = rgb[i].rgbtRed;
        pbmi->bmiColors[i].rgbGreen = rgb[i].rgbtGreen;
        pbmi->bmiColors[i].rgbBlue = rgb[i].rgbtBlue;
        pbmi->bmiColors[i].rgbReserved = 0;
      }
      pbmi->bmiHeader.biClrUsed = 16;
    }
    break;
    
  case 1: // BW
    pbmi->bmiColors[0].rgbRed = pbmi->bmiColors[0].rgbGreen = pbmi->bmiColors[0].rgbBlue = 0;
    pbmi->bmiColors[1].rgbRed = pbmi->bmiColors[1].rgbGreen = pbmi->bmiColors[1].rgbBlue = 255;
    pbmi->bmiColors[0].rgbReserved = pbmi->bmiColors[1].rgbReserved = 0;
    break;
    }
    
    // Try to create the bitmap section
    hRefDC = GetDC( NULL );
    hBitmap = ::CreateDIBSection( hRefDC, pbmi, DIB_RGB_COLORS, (void**)&pBits, NULL, 0 );
    int LastError = GetLastError();
    ReleaseDC( NULL, hRefDC );
    free( pbmi );
    
    if( hBitmap == NULL )
    {
      throw  BvcException( LastError, _T( "DSCreateDIBSection" ) );
    }
    
    return hBitmap;
}





/*!
  If the HPALETTE pointer is NULL, no palette is retreived.

  If the HPALETTE pointer is non-NULL, the palette is created by
  calling DSCreatePaletteForDIBSection. See its comments for 
  information regarding its functionality.
  
  The LoadImage() API is used to load the bitmap.
    
  \return
  - TRUE for success
  - FALSE for failure
*/
BOOL DSLoadDIBSectionFromBMPFile( 
                                 LPCTSTR szFileName, //!< Name of (BMP) file from which to obtain DIBSection
                                 HBITMAP *phBitmap,  //!< Pointer to handle which receives HBITMAP DIBSection
                                 HPALETTE *phPalette //!< Pointer to handle which receives Palette
                                 )
{
  if( phBitmap == NULL )
    throw  BvcException( Bvc::ErrorNumber( E_POINTER ), _T( "DSLoadDIBSectionFromBMPFile" ) );
  *phBitmap = NULL;
  
  if( phPalette != NULL )
    *phPalette = NULL;
  
  // Use LoadImage() to get the image loaded into a DIBSection
  *phBitmap = (HBITMAP)LoadImage( NULL, szFileName, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_DEFAULTSIZE | LR_LOADFROMFILE );
  if( *phBitmap == NULL )
    throw  BvcException( ::GetLastError(), _T( "DSLoadDIBSectionFromBMPFile" ) );
  
  // if they want a palette, get one
  if( phPalette != NULL )
    *phPalette = DSCreatePaletteForDIBSection( *phBitmap );
  
  return TRUE;
}




/*!
  The bitmap is drawn using StretchBlt() if the target DC is a screen
  DC and StretchDIBits() otherwise.

  A pallete is used, only if the target DC is a screen DC. A more 
  robust implementation might check RASTERCAPS to see if the target
  device is a palettized device.
  
  Also, the palette is selected as a background palette. If it is
  desirable to have the palette as a foreground palette, simply 
  obtain and realize the palette in the foreground before calling
  this function.
    
  \return 
  - TRUE for success
  - FALSE for failure     
*/
BOOL DSDrawDIBSectionOnDC( 
                          HDC hDC,         //< HDC on which to draw the DIBSection
                          HBITMAP hBitmap, //< the DIBSection to be drawn
                          LPRECT pRect     //< pointer to a rectangle containing the target coordinates
                          )
{
  DIBSECTION  ds;
  HPALETTE    hPal = NULL, hOldPal = NULL;
  BOOL        bRes;
  
  GetObject( hBitmap, sizeof(DIBSECTION), &ds );
  if( GetDeviceCaps( hDC, RASTERCAPS ) & RC_PALETTE )
  { // if it's a palette device, select and realize a palette
    // as a background palette (won't cause a problem is the
    // palette was not selected in the foreground in the main app
    hPal = DSCreatePaletteForDIBSection( hBitmap );
    hOldPal = SelectPalette( hDC, hPal, TRUE );
    RealizePalette( hDC );
  }
  if( GetDeviceCaps( hDC, TECHNOLOGY ) == DT_RASDISPLAY )
  { // going to the screen, use StretchBlt()
    HDC hMemDC;
    HBITMAP hOldBitmap;
    
    hMemDC = CreateCompatibleDC( hDC  );
    hOldBitmap = (HBITMAP)SelectObject( hMemDC, hBitmap );
    bRes = StretchBlt( hDC, pRect->left, pRect->top, 
      pRect->right-pRect->left, pRect->bottom-pRect->top, 
      hMemDC, 0, 0, ds.dsBm.bmWidth, ds.dsBm.bmHeight, SRCCOPY );
    SelectObject( hMemDC, hOldBitmap );
    DeleteDC( hMemDC );
  }
  else
  { // going to the printer, use StretchDIBits()
    LPBITMAPINFO    pbmi;
    
    // if the printer is palettized, 
    pbmi = DSGetBITMAPINFOForDIBSection( hBitmap );
    bRes = (GDI_ERROR != StretchDIBits( hDC, pRect->left, pRect->top, 
      pRect->right-pRect->left, pRect->bottom-pRect->top,
      0, 0, ds.dsBm.bmWidth, ds.dsBm.bmHeight, ds.dsBm.bmBits, 
      pbmi, DIB_RGB_COLORS, SRCCOPY ));
    free( pbmi );
  }
  if( GetDeviceCaps( hDC, RASTERCAPS ) & RC_PALETTE )
  {
    SelectPalette( hDC, hOldPal, TRUE );
    ::DeleteObject( hPal );
  }
  return bRes;
}




/*!
  \return 
  - TRUE for success
  - FALSE for failure
*/
BOOL DSStoreDIBSectionInBMPFile( 
                                LPCTSTR szFileName, //< Name of (BMP) file in which to store the DIBSection
                                HBITMAP hBitmap         //< handle for HBITMAP DIBSection to be stored

⌨️ 快捷键说明

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