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

📄 dibhelp.c

📁 Windows Programming source code
💻 C
📖 第 1 页 / 共 3 页
字号:

     switch (DibBitCount (hdib))
     {
     case  1:  * pPixel &= ~(1     << (7 - (x & 7))) ;
               * pPixel |= dwPixel << (7 - (x & 7)) ;
               break ;

     case  4:  * pPixel &= 0x0F    << (x & 1 ? 4 : 0) ;
               * pPixel |= dwPixel << (x & 1 ? 0 : 4) ;
               break ;

     case  8:  * pPixel = (BYTE) dwPixel ;
               break ;

     case 16:  * (WORD *) pPixel = (WORD) dwPixel ;
               break ;

     case 24:  * (RGBTRIPLE *) pPixel = * (RGBTRIPLE *) &dwPixel ; 
               break ;

     case 32:  * (DWORD *) pPixel = dwPixel ;
               break ;
     default:
          return FALSE ;
     }
     return TRUE ;
}

/*------------------------------------------------------
   DibGetPixelColor:  Obtains the pixel color at (x, y)
  ------------------------------------------------------*/

BOOL DibGetPixelColor (HDIB hdib, int x, int y, RGBQUAD * prgb)
{
     DWORD      dwPixel ;
     int        iBitCount ;
     PDIBSTRUCT pdib = hdib ;

          // Get bit count; also use this as a validity check

     if (0 == (iBitCount = DibBitCount (hdib)))
          return FALSE ;

          // Get the pixel value

     dwPixel = DibGetPixel (hdib, x, y) ;

          // If the bit-count is 8 or less, index the color table

     if (iBitCount <= 8)
          return DibGetColor (hdib, (int) dwPixel, prgb) ;

          // If the bit-count is 24, just use the pixel

     else if (iBitCount == 24)
     {
          * (RGBTRIPLE *) prgb = * (RGBTRIPLE *) & dwPixel ;
          prgb->rgbReserved = 0 ;
     }

          // If the bit-count is 32 and the biCompression field is BI_RGB,
          //   just use the pixel

     else if (iBitCount == 32 && 
               pdib->ds.dsBmih.biCompression == BI_RGB)
     {
          * prgb = * (RGBQUAD *) & dwPixel ;
     }

          // Otherwise, use the mask and shift values
          //   (for best performance, don't use DibMask and DibShift functions)
     else
     {
          prgb->rgbRed   = (BYTE) (((pdib->ds.dsBitfields[0] & dwPixel) 
                                   >> pdib->iRShift[0]) << pdib->iLShift[0]) ;

          prgb->rgbGreen = (BYTE) (((pdib->ds.dsBitfields[1] & dwPixel) 
                                   >> pdib->iRShift[1]) << pdib->iLShift[1]) ;

          prgb->rgbBlue  = (BYTE) (((pdib->ds.dsBitfields[2] & dwPixel) 
                                   >> pdib->iRShift[2]) << pdib->iLShift[2]) ;
     }
     return TRUE ;
}

/*---------------------------------------------------
   DibSetPixelColor:  Sets the pixel color at (x, y) 
  ---------------------------------------------------*/

BOOL DibSetPixelColor (HDIB hdib, int x, int y, RGBQUAD * prgb)
{
     DWORD      dwPixel ;
     int        iBitCount ;
     PDIBSTRUCT pdib = hdib ;

          // Don't do this function for DIBs with color tables

     iBitCount = DibBitCount (hdib) ;

     if (iBitCount <= 8)
          return FALSE ;

          // The rest is just the opposite of DibGetPixelColor

     else if (iBitCount == 24)
     {
          * (RGBTRIPLE *) & dwPixel = * (RGBTRIPLE *) prgb ;
          dwPixel &= 0x00FFFFFF ;
     }

     else if (iBitCount == 32 &&
               pdib->ds.dsBmih.biCompression == BI_RGB)
     {
          * (RGBQUAD *) & dwPixel = * prgb ;
     }

     else
     {
          dwPixel  = (((DWORD) prgb->rgbRed >> pdib->iLShift[0]) 
                         << pdib->iRShift[0]) ; 

          dwPixel |= (((DWORD) prgb->rgbGreen >> pdib->iLShift[1])
                         << pdib->iRShift[1]) ; 

          dwPixel |= (((DWORD) prgb->rgbBlue >> pdib->iLShift[2])
                         << pdib->iRShift[2]) ; 
     }

     DibSetPixel (hdib, x, y, dwPixel) ;
     return TRUE ;
}

/*--------------------------------------------------------------
   Calculating shift values from color masks is required by the 
     DibCreateFromInfo function.
  --------------------------------------------------------------*/

static int MaskToRShift (DWORD dwMask)
{
     int iShift ;

     if (dwMask == 0)
          return 0 ;

     for (iShift = 0 ; !(dwMask & 1) ; iShift++)
          dwMask >>= 1 ;

     return iShift ;
}

static int MaskToLShift (DWORD dwMask)
{
     int iShift ;

     if (dwMask == 0)
          return 0 ;

     while (!(dwMask & 1))
          dwMask >>= 1 ;

     for (iShift = 0 ; dwMask & 1 ; iShift++)
          dwMask >>= 1 ;

     return 8 - iShift ;
}

/*-------------------------------------------------------------------------
   DibCreateFromInfo: All DIB creation functions ultimately call this one.
     This function is responsible for calling CreateDIBSection, allocating
     memory for DIBSTRUCT, and setting up the row pointer.
  -------------------------------------------------------------------------*/

HDIB DibCreateFromInfo (BITMAPINFO * pbmi)
{
     BYTE      * pBits ;
     DIBSTRUCT * pdib ;
     HBITMAP     hBitmap ;
     int         i, iRowLength, cy, y ;
     
     hBitmap = CreateDIBSection (NULL, pbmi, DIB_RGB_COLORS, &pBits, NULL, 0) ;

     if (hBitmap == NULL)
          return NULL ;

     if (NULL == (pdib = malloc (sizeof (DIBSTRUCT))))
     {
          DeleteObject (hBitmap) ;
          return NULL ;
     }

     pdib->iSignature = HDIB_SIGNATURE ;
     pdib->hBitmap    = hBitmap ;
     pdib->pBits      = pBits ;

     GetObject (hBitmap, sizeof (DIBSECTION), &pdib->ds) ;

          // Notice that we can now use the DIB information functions 
          //   defined above.

          // If the compression is BI_BITFIELDS, calculate shifts from masks

     if (DibCompression (pdib) == BI_BITFIELDS)
     {
          for (i = 0 ; i < 3 ; i++)
          {
               pdib->iLShift[i] = MaskToLShift (pdib->ds.dsBitfields[i]) ;
               pdib->iRShift[i] = MaskToRShift (pdib->ds.dsBitfields[i]) ;
          }
     }

          // If the compression is BI_RGB, but bit-count is 16 or 32,
          //   set the bitfields and the masks

     else if (DibCompression (pdib) == BI_RGB)
     {
          if (DibBitCount (pdib) == 16)
          {
               pdib->ds.dsBitfields[0] = 0x00007C00 ;
               pdib->ds.dsBitfields[1] = 0x000003E0 ;
               pdib->ds.dsBitfields[2] = 0x0000001F ;

               pdib->iRShift[0] = 10 ;
               pdib->iRShift[1] =  5 ;
               pdib->iRShift[2] =  0 ; 

               pdib->iLShift[0] =  3 ;
               pdib->iLShift[1] =  3 ;
               pdib->iLShift[2] =  3 ;
          }
          else if (DibBitCount (pdib) == 24 || DibBitCount (pdib) == 32)
          {
               pdib->ds.dsBitfields[0] = 0x00FF0000 ;
               pdib->ds.dsBitfields[1] = 0x0000FF00 ;
               pdib->ds.dsBitfields[2] = 0x000000FF ;

               pdib->iRShift[0] = 16 ;
               pdib->iRShift[1] =  8 ;
               pdib->iRShift[2] =  0 ; 

               pdib->iLShift[0] =  0 ;
               pdib->iLShift[1] =  0 ;
               pdib->iLShift[2] =  0 ;
          }
     }
          // Allocate an array of pointers to each row in the DIB

     cy = DibHeight (pdib) ;

     if (NULL == (pdib->ppRow = malloc (cy * sizeof (BYTE *))))
     {
          free (pdib) ;
          DeleteObject (hBitmap) ;
          return NULL ;
     }

          // Initialize them.

     iRowLength = DibRowLength (pdib) ; 

     if (pbmi->bmiHeader.biHeight > 0)       // ie, bottom up
     {
          for (y = 0 ; y < cy ; y++)
               pdib->ppRow[y] = pBits + (cy - y - 1) * iRowLength ;
     }
     else                                    // top down
     {
          for (y = 0 ; y < cy ; y++)
               pdib->ppRow[y] = pBits + y * iRowLength ;
     }
     return pdib ;
}

/*--------------------------------------------------
   DibDelete:  Frees all memory for the DIB section
  --------------------------------------------------*/

BOOL DibDelete (HDIB hdib)
{
     DIBSTRUCT * pdib = hdib ;

     if (!DibIsValid (hdib))
          return FALSE ;

     free (pdib->ppRow) ;
     DeleteObject (pdib->hBitmap) ;
     free (pdib) ;
     return TRUE ;
}

/*----------------------------------------------------
   DibCreate: Creates an HDIB from explicit arguments
  ----------------------------------------------------*/ 

HDIB DibCreate (int cx, int cy, int cBits, int cColors)
{
     BITMAPINFO * pbmi ;
     DWORD        dwInfoSize ;
     HDIB         hDib ;
     int          cEntries ;

     if (cx <= 0 || cy <= 0 || 
         ((cBits !=  1) && (cBits !=  4) && (cBits !=  8) && 
          (cBits != 16) && (cBits != 24) && (cBits != 32)))
     {
          return NULL ;
     }

     if (cColors != 0)
          cEntries = cColors ;
     else if (cBits <= 8)
          cEntries = 1 << cBits ;

     dwInfoSize = sizeof (BITMAPINFOHEADER) + (cEntries - 1) * sizeof (RGBQUAD);

     if (NULL == (pbmi = malloc (dwInfoSize)))
     {
          return NULL ;
     }

     ZeroMemory (pbmi, dwInfoSize) ;

     pbmi->bmiHeader.biSize          = sizeof (BITMAPINFOHEADER) ;
     pbmi->bmiHeader.biWidth         = cx ;
     pbmi->bmiHeader.biHeight        = cy ;
     pbmi->bmiHeader.biPlanes        = 1 ;
     pbmi->bmiHeader.biBitCount      = cBits ;
     pbmi->bmiHeader.biCompression   = BI_RGB ;
     pbmi->bmiHeader.biSizeImage     = 0 ;
     pbmi->bmiHeader.biXPelsPerMeter = 0 ;
     pbmi->bmiHeader.biYPelsPerMeter = 0 ;
     pbmi->bmiHeader.biClrUsed       = cColors ;
     pbmi->bmiHeader.biClrImportant  = 0 ;

     hDib = DibCreateFromInfo (pbmi) ;
     free (pbmi) ;

     return hDib ;
}

/*--------------------------------------------------
   DibCopyToInfo:  Builds BITMAPINFO structure.
                   Used by DibCopy and DibCopyToDdb
  --------------------------------------------------*/

static BITMAPINFO * DibCopyToInfo (HDIB hdib)
{
     BITMAPINFO * pbmi ;
     int          i, iNumColors ;
     RGBQUAD    * prgb ;

     if (!DibIsValid (hdib))
          return NULL ;

          // Allocate the memory

     if (NULL == (pbmi = malloc (DibInfoSize (hdib))))
          return NULL ;

          // Copy the information header

     CopyMemory (pbmi, DibInfoHeaderPtr (hdib), 
                                        sizeof (BITMAPINFOHEADER));
          
          // Copy the possible color masks

     prgb = (RGBQUAD *) ((BYTE *) pbmi + sizeof (BITMAPINFOHEADER)) ;

     if (DibMaskSize (hdib))
     {
          CopyMemory (prgb, DibMaskPtr (hdib), 3 * sizeof (DWORD)) ;

          prgb = (RGBQUAD *) ((BYTE *) prgb + 3 * sizeof (DWORD)) ;
     }
          // Copy the color table

⌨️ 快捷键说明

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