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

📄 dibsectn.cpp

📁 BCAM 1394 Driver
💻 CPP
📖 第 1 页 / 共 2 页
字号:
                                )
{
  HANDLE              hFile;
  BITMAPFILEHEADER    bfh;
  LPBITMAPINFO        pbmi;
  DWORD               dwTotalDIBBytes, dwSize, dwWritten;
  LPBYTE              pBits;
  
  // Open the file for writing (overwrites any previous version of that file)
  if( (hFile=CreateFile(szFileName,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL)) == INVALID_HANDLE_VALUE )
    return FALSE;
  // Get the BITMAPINFO for the DIBSection
  if( (pbmi = DSGetBITMAPINFOForDIBSection( hBitmap )) == NULL )
  {
    CloseHandle( hFile );
    return FALSE;
  }
  // What's the total size of the DIB information (not counting file header)?
  dwTotalDIBBytes = DSTotalBytesSize( pbmi );
  // Construct the file header
  ZeroMemory( &bfh, sizeof(BITMAPFILEHEADER) );
  bfh.bfType          = 0x4d42; // 'BM'
  bfh.bfSize          = dwTotalDIBBytes + sizeof(BITMAPFILEHEADER);
  bfh.bfReserved1     = 0;
  bfh.bfReserved2     = 0;
  bfh.bfOffBits       = (DWORD)(sizeof(BITMAPFILEHEADER) + pbmi->bmiHeader.biSize + DSColorTableSize(pbmi) );
  // Write the file header
  if( ( ! WriteFile( hFile, &bfh, sizeof(BITMAPFILEHEADER), &dwWritten, NULL ) ) || 
    ( dwWritten != sizeof(BITMAPFILEHEADER) ) )
  {
    free( pbmi );
    CloseHandle( hFile );
    return FALSE;
  }
  // Write the BITMAPINFO
  dwSize = sizeof(BITMAPINFOHEADER) + DSColorTableSize( pbmi );
  if( ( ! WriteFile( hFile, pbmi, dwSize, &dwWritten, NULL ) ) || 
    ( dwWritten != dwSize ) )
  {
    free( pbmi );
    CloseHandle( hFile );
    return FALSE;
  }
  // Write the bits
  pBits = DSGetPointerToDIBSectionImageBits( hBitmap );
  dwSize = DSImageBitsSize( pbmi );
  if( ( ! WriteFile( hFile, pBits, dwSize, &dwWritten, NULL ) ) || 
    ( dwWritten != dwSize ) )
  {
    free( pbmi );
    CloseHandle( hFile );
    return FALSE;
  }
  // clean up and leave
  free( pbmi );
  CloseHandle( hFile );
  return TRUE;
}



/*!
  Creates a palette to be used to display the DIBSection on a 
  palettized display device.

  If the DIBSection contains a color table, those colors are used 
  to create the palette. However, if the DIBSection is greater than
  8bpp (ie sans color table), then a suitable palette is derived
  from either CreateHalftonePalette() or GetStockObject() depending
  on the video mode.

  \return
  a palette which can be used to display the DIBSection on palettized devices
*/
HPALETTE DSCreatePaletteForDIBSection( 
                                      HBITMAP hBitmap //!< a DIBSection for which to get a palette
                                      )
{
  BITMAP      bm;
  HPALETTE    hPalette;
  
  // Get the color depth of the DIBSection
  GetObject( hBitmap, sizeof(BITMAP), &bm );
  
  // If the DIBSection is 256 color or less, it has a color table
  if( ( bm.bmBitsPixel * bm.bmPlanes ) <= 8 )
  {
    HDC             hMemDC;
    HBITMAP         hOldBitmap;
    RGBQUAD         rgb[256];
    LPLOGPALETTE    pLogPal;
    WORD            i;
    int             nColors;
    
    // Find out how many colors are in the color table
    nColors = 1 << ( bm.bmBitsPixel * bm.bmPlanes );
    // Create a memory DC and select the DIBSection into it
    hMemDC = CreateCompatibleDC( NULL );
    hOldBitmap = (HBITMAP)SelectObject( hMemDC, hBitmap );
    // Get the DIBSection's color table
    GetDIBColorTable( hMemDC, 0, nColors, rgb );
    // Create a palette from the color table
    pLogPal = (LOGPALETTE*)malloc( sizeof(LOGPALETTE) + (nColors*sizeof(PALETTEENTRY)) );
    pLogPal->palVersion = 0x300;
    pLogPal->palNumEntries = WORD( nColors );
    for(i=0;i<nColors;i++)
    {
      pLogPal->palPalEntry[i].peRed = rgb[i].rgbRed;
      pLogPal->palPalEntry[i].peGreen = rgb[i].rgbGreen;
      pLogPal->palPalEntry[i].peBlue = rgb[i].rgbBlue;
      pLogPal->palPalEntry[i].peFlags = 0;
    }
    hPalette = CreatePalette( pLogPal );
    // Clean up
    free( pLogPal );
    SelectObject( hMemDC, hOldBitmap );
    DeleteDC( hMemDC );
  }
  else   // It has no color table, so make one up
  {
    hPalette = DSCreateSpectrumPalette();
  }
  return hPalette;
}




/*!
  The returned BITMAPINFO contains a color table, even if the 
  bit-depth does not require one - this way the caller can override
  the optional color table if need be.

  The caller is responsible for de-allocating the memory block using
  the CRT function free().

  \return
  a pointer to a newly allocated memory block containing
  the BITMAPINFO structure which describes the DIBSection.
*/
LPBITMAPINFO DSGetBITMAPINFOForDIBSection( 
                                          HBITMAP hBitmap //!< a DIBSection for which to get the BITMAPINFO
                                          )
{
  LPBITMAPINFO    pbmi;
  DIBSECTION      ds;
  LPRGBQUAD       prgb;
  
  GetObject( hBitmap, sizeof(DIBSECTION), &ds );
  // load the header and the bitmasks if present
  // per function comments above, we allocate space for a color 
  // table even if it is not needed 
  if( ds.dsBmih.biCompression == BI_BITFIELDS )
  {   // has a bitmask - be sure to allocate for and copy them
    pbmi = (BITMAPINFO*)malloc( sizeof(BITMAPINFOHEADER) + (3*sizeof(DWORD)) + (256*sizeof(RGBQUAD)) );
    CopyMemory( &(pbmi->bmiHeader), &(ds.dsBmih), sizeof(BITMAPINFOHEADER) + (3*sizeof(DWORD)) );
    prgb = (LPRGBQUAD)&(pbmi->bmiColors[3]);
  }
  else
  {   // no bitmask - just the header and color table
    pbmi = (BITMAPINFO*)malloc( sizeof(BITMAPINFOHEADER) + (256*sizeof(RGBQUAD)) );
    CopyMemory( &(pbmi->bmiHeader), &(ds.dsBmih), sizeof(BITMAPINFOHEADER) );
    prgb = pbmi->bmiColors;
  }
  // at this point, prgb points to the color table, even 
  // if bitmasks are present
  
  // Now for the color table
  if( ( ds.dsBm.bmBitsPixel * ds.dsBm.bmPlanes ) <= 8 )
  {   // the DIBSection is 256 color or less (has color table)
    HDC             hMemDC;
    HBITMAP         hOldBitmap;
    hMemDC = CreateCompatibleDC( NULL );
    hOldBitmap = (HBITMAP)SelectObject( hMemDC, hBitmap );
    GetDIBColorTable( hMemDC, 0, 1<<(ds.dsBm.bmBitsPixel*ds.dsBm.bmPlanes), prgb );
    SelectObject( hMemDC, hOldBitmap );
    DeleteDC( hMemDC );
  }
  else
  {   // the DIBSection is >8bpp (has no color table) so make one up
    HPALETTE        hPal;
    PALETTEENTRY    pe[256];
    int             i;
    
    // where are we going to get the colors? from a spectrum palette
    hPal = DSCreateSpectrumPalette();
    GetPaletteEntries( hPal, 0, 256, pe );
    for(i=0;i<256;i++)
    {
      prgb[i].rgbRed = pe[i].peRed;
      prgb[i].rgbGreen = pe[i].peGreen;
      prgb[i].rgbBlue = pe[i].peBlue;
      prgb[i].rgbReserved = 0;
    }
    ::DeleteObject( hPal );
    pbmi->bmiHeader.biClrUsed = 256;
  }
  return pbmi;
}



/*!
  \return
  the size, in bytes, of the color table for the DIB
*/
DWORD DSColorTableSize( 
                       LPBITMAPINFO pbmi //!< pointer to a BITMAPINFO describing a DIB
                       )
{
  DWORD dwColors;
  
  dwColors = 0;
  if( pbmi->bmiHeader.biClrUsed != 0 )
    dwColors = pbmi->bmiHeader.biClrUsed;
  else if( pbmi->bmiHeader.biBitCount > 8 )
    dwColors = 0;
  else
    dwColors = 1 << (pbmi->bmiHeader.biBitCount * pbmi->bmiHeader.biPlanes);
  
  if( pbmi->bmiHeader.biCompression == BI_BITFIELDS )
    return (sizeof(DWORD)*3) + (dwColors*sizeof(RGBQUAD));
  return (dwColors*sizeof(RGBQUAD));
}


/*!
  \return 
  the size, in bytes, of the DIB's image bits
*/
DWORD DSImageBitsSize(  
                      LPBITMAPINFO pbmi //!< pointer to a BITMAPINFO describing a DIB
                      )
{
  switch( pbmi->bmiHeader.biCompression )
  {
  case BI_RLE8:
  case BI_RLE4:
    return pbmi->bmiHeader.biSizeImage;
    break;
  default: // should not have to use "default"
  case BI_RGB:
  case BI_BITFIELDS:
    return BYTESPERLINE(pbmi->bmiHeader.biWidth,pbmi->bmiHeader.biBitCount*pbmi->bmiHeader.biPlanes)*pbmi->bmiHeader.biHeight;
    break;
  }
  // return 0;
}



/*!
  \return
  the size, in bytes, of the DIB's memory footprint
*/
DWORD DSTotalBytesSize( 
                       LPBITMAPINFO pbmi //!< pointer to a BITMAPINFO describing a DIB
                       )
{
  return DSImageBitsSize(pbmi) + sizeof(BITMAPINFOHEADER) + DSColorTableSize(pbmi);
}



/*!
  \return
  pointer to the bitmap's bits
*/
LPBYTE DSGetPointerToDIBSectionImageBits( 
                                         HBITMAP hBitmap //!< handle for HBITMAP DIBSection
                                         )
{
  DIBSECTION  ds;
  
  GetObject( hBitmap, sizeof(DIBSECTION), &ds );
  return (LPBYTE)ds.dsBm.bmBits;
}



/*!
This function was stolen from Mike Irvine's SEEDIB sample. There's
no source code comments in his version either :)

  This function will build a palette with a spectrum of colors.  It is
  useful when you want to display a number of DIBs each with a different
  palette yet still have an a good selection of colors to which the 
  DIBs' colors will be mapped.
  
    \return
    a handle to a spectrum palette - NULL on failure
*/
HPALETTE DSCreateSpectrumPalette( void ) 
{                 
  HPALETTE hPal;
  LPLOGPALETTE lplgPal;
  BYTE red, green, blue;
  int i; 
  
  lplgPal = (LPLOGPALETTE)GlobalAlloc( GPTR, sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) * 256 ); 
  if (!lplgPal)
    return NULL;
  
  lplgPal->palVersion = 0x300;
  lplgPal->palNumEntries = 256;
  
  red = green = blue = 0;
  for (i = 0; i < 256; i++) {
    lplgPal->palPalEntry[i].peRed   = red;
    lplgPal->palPalEntry[i].peGreen = green;
    lplgPal->palPalEntry[i].peBlue  = blue;
    lplgPal->palPalEntry[i].peFlags = (BYTE)0;
    
    if (!(red += 32))
      if (!(green += 32))
        blue += 64;
  }
  hPal = CreatePalette(lplgPal);
  GlobalFree(lplgPal);
  return hPal;
}

⌨️ 快捷键说明

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