📄 dibapi.cpp
字号:
*
************************************************************************/
LPSTR WINAPI FindDIBBits(LPSTR lpbi)
{
if(lpbi==NULL)
return NULL;
return (lpbi + *(LPDWORD)lpbi + ::PaletteSize(lpbi));
}
/*************************************************************************
*
* DIBWidth()
*
* Parameter:
*
* LPSTR lpbi - pointer to packed-DIB memory block
*
* Return Value:
*
* DWORD - width of the DIB
*
* Description:
*
* This function gets the width of the DIB from the BITMAPINFOHEADER
* width field if it is a Windows 3.0-style DIB or from the BITMAPCOREHEADER
* width field if it is an other-style DIB.
*
************************************************************************/
DWORD WINAPI DIBWidth(LPSTR lpDIB)
{
LPBITMAPINFOHEADER lpbmi; // pointer to a Win 3.0-style DIB
LPBITMAPCOREHEADER lpbmc; // pointer to an other-style DIB
/* point to the header (whether Win 3.0 and old) */
lpbmi = (LPBITMAPINFOHEADER)lpDIB;
lpbmc = (LPBITMAPCOREHEADER)lpDIB;
/* return the DIB width if it is a Win 3.0 DIB */
if (IS_WIN30_DIB(lpDIB))
return lpbmi->biWidth;
else /* it is an other-style DIB, so return its width */
return (DWORD)lpbmc->bcWidth;
}
/*************************************************************************
*
* DIBHeight()
*
* Parameter:
*
* LPSTR lpbi - pointer to packed-DIB memory block
*
* Return Value:
*
* DWORD - height of the DIB
*
* Description:
*
* This function gets the height of the DIB from the BITMAPINFOHEADER
* height field if it is a Windows 3.0-style DIB or from the BITMAPCOREHEADER
* height field if it is an other-style DIB.
*
************************************************************************/
DWORD WINAPI DIBHeight(LPSTR lpDIB)
{
if(lpDIB==NULL)
return 0;
LPBITMAPINFOHEADER lpbmi; // pointer to a Win 3.0-style DIB
LPBITMAPCOREHEADER lpbmc; // pointer to an other-style DIB
/* point to the header (whether old or Win 3.0 */
lpbmi = (LPBITMAPINFOHEADER)lpDIB;
lpbmc = (LPBITMAPCOREHEADER)lpDIB;
/* return the DIB height if it is a Win 3.0 DIB */
if (IS_WIN30_DIB(lpDIB))
return lpbmi->biHeight;
else /* it is an other-style DIB, so return its height */
return (DWORD)lpbmc->bcHeight;
}
/*************************************************************************
*
* PaletteSize()
*
* Parameter:
*
* LPSTR lpbi - pointer to packed-DIB memory block
*
* Return Value:
*
* WORD - size of the color palette of the DIB
*
* Description:
*
* This function gets the size required to store the DIB's palette by
* multiplying the number of colors by the size of an RGBQUAD (for a
* Windows 3.0-style DIB) or by the size of an RGBTRIPLE (for an other-
* style DIB).
*
************************************************************************/
WORD WINAPI PaletteSize(LPSTR lpbi)
{
/* calculate the size required by the palette */
if (IS_WIN30_DIB (lpbi))
return (WORD)(::DIBNumColors(lpbi) * sizeof(RGBQUAD));
else
return (WORD)(::DIBNumColors(lpbi) * sizeof(RGBTRIPLE));
}
/*************************************************************************
*
* DIBNumColors()
*
* Parameter:
*
* LPSTR lpbi - pointer to packed-DIB memory block
*
* Return Value:
*
* WORD - number of colors in the color table
*
* Description:
*
* This function calculates the number of colors in the DIB's color table
* by finding the bits per pixel for the DIB (whether Win3.0 or other-style
* DIB). If bits per pixel is 1: colors=2, if 4: colors=16, if 8: colors=256,
* if 24, no colors in color table.
*
************************************************************************/
WORD WINAPI DIBNumColors(LPSTR lpbi)
{
WORD wBitCount; // DIB bit count
/* If this is a Windows-style DIB, the number of colors in the
* color table can be less than the number of bits per pixel
* allows for (i.e. lpbi->biClrUsed can be set to some value).
* If this is the case, return the appropriate value.
*/
if (IS_WIN30_DIB(lpbi))
{
DWORD dwClrUsed;
dwClrUsed = ((LPBITMAPINFOHEADER)lpbi)->biClrUsed;
if (dwClrUsed != 0)
return (WORD)dwClrUsed;
}
/* Calculate the number of colors in the color table based on
* the number of bits per pixel for the DIB.
*/
if (IS_WIN30_DIB(lpbi))
wBitCount = ((LPBITMAPINFOHEADER)lpbi)->biBitCount;
else
wBitCount = ((LPBITMAPCOREHEADER)lpbi)->bcBitCount;
/* return number of colors based on bits per pixel */
switch (wBitCount)
{
case 1:
return 2;
case 4:
return 16;
case 8:
return 256;
default:
return 0;
}
}
//////////////////////////////////////////////////////////////////////////
//// Clipboard support
//---------------------------------------------------------------------
//
// Function: CopyHandle (from SDK DibView sample clipbrd.c)
//
// Purpose: Makes a copy of the given global memory block. Returns
// a handle to the new memory block (NULL on error).
//
// Routine stolen verbatim out of ShowDIB.
//
// Parms: h == Handle to global memory to duplicate.
//
// Returns: Handle to new global memory block.
//
//---------------------------------------------------------------------
HGLOBAL WINAPI CopyHandle (HGLOBAL h)
{
if (h == NULL)
return NULL;
DWORD dwLen = ::GlobalSize((HGLOBAL) h);
HGLOBAL hCopy = ::GlobalAlloc(GHND, dwLen);
if (hCopy != NULL)
{
void* lpCopy = ::GlobalLock((HGLOBAL) hCopy);
void* lp = ::GlobalLock((HGLOBAL) h);
memcpy(lpCopy, lp, dwLen);
::GlobalUnlock(hCopy);
::GlobalUnlock(h);
}
return hCopy;
}
//
/*
FUNCTION : BytesPerLIne
PURPOSE : Calculate the nember of bytes in one line
PARAMS : LPBYTE lpDIB --pointer to the BITMAPINFOHEADER
that begins the DF_DIB block
RETURNS : DWORD ----number of bytes in one scan line
*/
DWORD WINAPI BytesPerLine(LPBYTE lpDIB)
{
return WIDTHBYTES(((LPBITMAPINFOHEADER)lpDIB)->biWidth*
((LPBITMAPINFOHEADER)lpDIB)->biPlanes*
((LPBITMAPINFOHEADER)lpDIB)->biBitCount);
}
DWORD WINAPI BytesPerLine( LPBITMAPINFOHEADER lpBMIH )
{
return WIDTHBYTES(lpBMIH->biWidth * lpBMIH->biPlanes * lpBMIH->biBitCount);
}
/*
FUNCTION : DIBlockSize
PURPOSE : Calculate the nembers of bytes in one DIB image
*/
DWORD WINAPI DIBlockSize(LPBYTE lpDIB)
{
if(((LPBITMAPINFOHEADER)lpDIB)->biSizeImage==0)
((LPBITMAPINFOHEADER)lpDIB)->biSizeImage=
(::BytesPerLine(lpDIB))*((LPBITMAPINFOHEADER)lpDIB)->biHeight;
return ((LPBITMAPINFOHEADER)lpDIB)->biSize+
PaletteSize((LPSTR)lpDIB) +((LPBITMAPINFOHEADER)lpDIB)->biSizeImage;
}
HDIB WINAPI ConvertDIBFormat( LPBYTE lpDIB,UINT nbpp,HPALETTE hPalScr)
{
LPBITMAPINFO lpSrcDIB;
LPBITMAPINFO lpbmi = NULL;
LPBYTE lpSourceBits, lpTargetBits, lpResult;
HDC hDC = NULL, hSourceDC, hTargetDC;
HBITMAP hSourceBitmap, hTargetBitmap, hOldTargetBitmap, hOldSourceBitmap;
DWORD dwSourceBitsSize, dwTargetBitsSize, dwTargetHeaderSize,dwColorNum;
HDIB hDib;
// Allocate and fill out a BITMAPINFO struct for the new DIB
// Allow enough room for a 256-entry color table, just in case
if(nbpp<=8)
dwColorNum=1<<nbpp;
else
dwColorNum=0;
if(!lpDIB)
return NULL;
lpSrcDIB=(LPBITMAPINFO)lpDIB;
dwTargetHeaderSize = sizeof( BITMAPINFO ) + ( dwColorNum * sizeof( RGBQUAD ) );
lpbmi =(LPBITMAPINFO) malloc( dwTargetHeaderSize );
lpbmi->bmiHeader.biSize = sizeof( BITMAPINFOHEADER );
lpbmi->bmiHeader.biWidth = lpSrcDIB->bmiHeader.biWidth;
lpbmi->bmiHeader.biHeight =lpSrcDIB->bmiHeader.biHeight;
lpbmi->bmiHeader.biPlanes = 1;
lpbmi->bmiHeader.biBitCount = nbpp;
lpbmi->bmiHeader.biCompression = BI_RGB;
lpbmi->bmiHeader.biSizeImage = 0;
lpbmi->bmiHeader.biXPelsPerMeter = 0;
lpbmi->bmiHeader.biYPelsPerMeter = 0;
lpbmi->bmiHeader.biClrUsed = 0;
lpbmi->bmiHeader.biClrImportant = 0;
// Fill in the color table
if( ! CopyColorTable( lpbmi,lpSrcDIB,hPalScr ) )
{
free( lpbmi );
return NULL;
}
// Gonna use DIBSections and BitBlt() to do the conversion, so make 'em
hDC = GetDC( NULL );
hTargetBitmap = CreateDIBSection( hDC, lpbmi, DIB_RGB_COLORS,(VOID**) &lpTargetBits, NULL, 0 );
hSourceBitmap = CreateDIBSection( hDC, lpSrcDIB, DIB_RGB_COLORS,(VOID**) &lpSourceBits, NULL, 0 );
hSourceDC = CreateCompatibleDC( hDC );
hTargetDC = CreateCompatibleDC( hDC );
// Flip the bits on the source DIBSection to match the source DIB
dwSourceBitsSize = lpSrcDIB->bmiHeader.biHeight * (::BytesPerLine(&(lpSrcDIB->bmiHeader)));
dwTargetBitsSize = lpbmi->bmiHeader.biHeight * (::BytesPerLine(&(lpbmi->bmiHeader)));
memcpy( lpSourceBits, FindDIBBits((LPSTR)lpSrcDIB), dwSourceBitsSize );
// Select DIBSections into DCs
hOldSourceBitmap = (HBITMAP)SelectObject( hSourceDC, hSourceBitmap );
hOldTargetBitmap = (HBITMAP)SelectObject( hTargetDC, hTargetBitmap );
// Set the color tables for the DIBSections
if( lpSrcDIB->bmiHeader.biBitCount <= 8 )
SetDIBColorTable( hSourceDC, 0, 1 << lpSrcDIB->bmiHeader.biBitCount, lpSrcDIB->bmiColors );
if( lpbmi->bmiHeader.biBitCount <= 8 )
SetDIBColorTable( hTargetDC, 0, 1 << lpbmi->bmiHeader.biBitCount, lpbmi->bmiColors );
/*
// If we are asking for a straight copy, do it
if( (lpSrcDIB->bmiHeader.biWidth==lpbmi->bmiHeader.biWidth) && (lpSrcDIB->bmiHeader.biHeight==lpbmi->bmiHeader.biHeight) )
{*/
BitBlt( hTargetDC, 0, 0, lpbmi->bmiHeader.biWidth, lpbmi->bmiHeader.biHeight, hSourceDC, 0, 0, SRCCOPY );
/*}
else
{
// else, should we stretch it?
if( bStretch )
{
SetStretchBltMode( hTargetDC, COLORONCOLOR );
StretchBlt( hTargetDC, 0, 0, lpbmi->bmiHeader.biWidth, lpbmi->bmiHeader.biHeight, hSourceDC, 0, 0, lpSrcDIB->bmiHeader.biWidth, lpSrcDIB->bmiHeader.biHeight, SRCCOPY );
}
else
{
// or just take the upper left corner of the source
BitBlt( hTargetDC, 0, 0, lpbmi->bmiHeader.biWidth, lpbmi->bmiHeader.biHeight, hSourceDC, 0, 0, SRCCOPY );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -