📄 dibhelp.c
字号:
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 + -