📄 dibutil.c
字号:
hPal = CreatePalette(lpLogPal);
/* clean up */
GlobalUnlock(hLogPal);
GlobalFree(hLogPal);
ReleaseDC(NULL, hDC);
return hPal;
}
/*************************************************************************
*
* AllocRoomForDIB()
*
* Parameters:
*
* BITMAPINFOHEADER - bitmap info header stucture
*
* HBITMAP - handle to the bitmap
*
* Return Value:
*
* HDIB - handle to memory block
*
* Description:
*
* This routine takes a BITMAPINOHEADER, and returns a handle to global
* memory which can contain a DIB with that header. It also initializes
* the header portion of the global memory. GetDIBits() is used to determine
* the amount of room for the DIB's bits. The total amount of memory
* needed = sizeof(BITMAPINFOHEADER) + size of color table + size of bits.
*
* History: Date Author Reason
* 6/01/91 Garrett McAuliffe Created
* 12/11/91 Patrick Schreiber Added header and some comments
*
************************************************************************/
HANDLE AllocRoomForDIB(BITMAPINFOHEADER bi, HBITMAP hBitmap)
{
DWORD dwLen;
HANDLE hDIB;
HDC hDC;
LPBITMAPINFOHEADER lpbi;
HANDLE hTemp;
/* Figure out the size needed to hold the BITMAPINFO structure
* (which includes the BITMAPINFOHEADER and the color table).
*/
dwLen = bi.biSize + PaletteSize((LPSTR) &bi);
hDIB = GlobalAlloc(GHND,dwLen);
/* Check that DIB handle is valid */
if (!hDIB)
return NULL;
/* Set up the BITMAPINFOHEADER in the newly allocated global memory,
* then call GetDIBits() with lpBits = NULL to have it fill in the
* biSizeImage field for us.
*/
lpbi = (VOID FAR *)GlobalLock(hDIB);
*lpbi = bi;
hDC = GetDC(NULL);
GetDIBits(hDC, hBitmap, 0, (WORD) bi.biHeight,
NULL, (LPBITMAPINFO) lpbi, DIB_RGB_COLORS);
ReleaseDC(NULL, hDC);
/* If the driver did not fill in the biSizeImage field,
* fill it in -- NOTE: this is a bug in the driver!
*/
if (lpbi->biSizeImage == 0)
lpbi->biSizeImage = WIDTHBYTES((DWORD)lpbi->biWidth * lpbi->biBitCount) *
lpbi->biHeight;
/* Get the size of the memory block we need */
dwLen = lpbi->biSize + PaletteSize((LPSTR) &bi) + lpbi->biSizeImage;
/* Unlock the memory block */
GlobalUnlock(hDIB);
/* ReAlloc the buffer big enough to hold all the bits */
if (hTemp = GlobalReAlloc(hDIB,dwLen,0))
return hTemp;
else
{
/* Else free memory block and return failure */
GlobalFree(hDIB);
return NULL;
}
}
/*************************************************************************
*
* ChangeDIBFormat()
*
* Parameter:
*
* HDIB - handle to packed-DIB in memory
*
* WORD - desired bits per pixel
*
* DWORD - desired compression format
*
* Return Value:
*
* HDIB - handle to the new DIB if successful, else NULL
*
* Description:
*
* This function will convert the bits per pixel and/or the compression
* format of the specified DIB. Note: If the conversion was unsuccessful,
* we return NULL. The original DIB is left alone. Don't use code like the
* following:
*
* hMyDIB = ChangeDIBFormat(hMyDIB, 8, BI_RLE4);
*
* The conversion will fail, but hMyDIB will now be NULL and the original
* DIB will now hang around in memory. We could have returned the old
* DIB, but we wanted to allow the programmer to check whether this
* conversion succeeded or failed.
*
* History:
*
* Date Author Reason
* 6/01/91 Garrett McAuliffe Created
* 12/10/91 Patrick Schreiber Modified from converting RGB to RLE8
* to converting RGB/RLE to RGB/RLE.
* Added wBitCount and dwCompression
* parameters. Also added header and
* comments.
*
************************************************************************/
HDIB FAR ChangeDIBFormat(HDIB hDIB, WORD wBitCount, DWORD dwCompression)
{
HDC hDC; // Handle to DC
HBITMAP hBitmap; // Handle to bitmap
BITMAP Bitmap; // BITMAP data structure
BITMAPINFOHEADER bi; // Bitmap info header
LPBITMAPINFOHEADER lpbi; // Pointer to bitmap info
HDIB hNewDIB = NULL; // Handle to new DIB
HPALETTE hPal, hOldPal; // Handle to palette, prev pal
WORD DIBBPP, NewBPP; // DIB bits per pixel, new bpp
DWORD DIBComp, NewComp;// DIB compression, new compression
/* Check for a valid DIB handle */
if (!hDIB)
return NULL;
/* Get the old DIB's bits per pixel and compression format */
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
DIBBPP = ((LPBITMAPINFOHEADER)lpbi)->biBitCount;
DIBComp = ((LPBITMAPINFOHEADER)lpbi)->biCompression;
GlobalUnlock(hDIB);
/* Validate wBitCount and dwCompression
* They must match correctly (i.e., BI_RLE4 and 4 BPP or
* BI_RLE8 and 8BPP, etc.) or we return failure */
if (wBitCount == 0)
{
NewBPP = DIBBPP;
if ((dwCompression == BI_RLE4 && NewBPP == 4) ||
(dwCompression == BI_RLE8 && NewBPP == 8) ||
(dwCompression == BI_RGB))
NewComp = dwCompression;
else
return NULL;
}
else if (wBitCount == 1 && dwCompression == BI_RGB)
{
NewBPP = wBitCount;
NewComp = BI_RGB;
}
else if (wBitCount == 4)
{
NewBPP = wBitCount;
if (dwCompression == BI_RGB || dwCompression == BI_RLE4)
NewComp = dwCompression;
else
return NULL;
}
else if (wBitCount == 8)
{
NewBPP = wBitCount;
if (dwCompression == BI_RGB || dwCompression == BI_RLE8)
NewComp = dwCompression;
else
return NULL;
}
else if (wBitCount == 24 && dwCompression == BI_RGB)
{
NewBPP = wBitCount;
NewComp = BI_RGB;
}
else
return NULL;
/* Save the old DIB's palette */
hPal = CreateDIBPalette(hDIB);
if (!hPal)
return NULL;
/* Convert old DIB to a bitmap */
hBitmap = DIBToBitmap(hDIB, hPal);
if (!hBitmap)
{
DeleteObject(hPal);
return NULL;
}
/* Get info about the bitmap */
GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap);
/* Fill in the BITMAPINFOHEADER appropriately */
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = Bitmap.bmWidth;
bi.biHeight = Bitmap.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = NewBPP;
bi.biCompression = NewComp;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
/* Go allocate room for the new DIB */
hNewDIB = AllocRoomForDIB(bi, hBitmap);
if (!hNewDIB)
return NULL;
/* Get a pointer to the new DIB */
lpbi = (VOID FAR *)GlobalLock(hNewDIB);
/* Get a DC and select/realize our palette in it */
hDC = GetDC(NULL);
hOldPal = SelectPalette(hDC, hPal, FALSE);
RealizePalette(hDC);
/* Call GetDIBits and get the new DIB bits */
if (!GetDIBits(hDC, hBitmap, 0, (WORD) lpbi->biHeight,
(LPSTR)lpbi + (WORD)lpbi->biSize + PaletteSize((LPSTR)lpbi),
(LPBITMAPINFO)lpbi, DIB_RGB_COLORS))
{
GlobalUnlock(hNewDIB);
GlobalFree(hNewDIB);
hNewDIB = NULL;
}
/* Clean up and return */
SelectPalette(hDC, hOldPal, TRUE);
RealizePalette(hDC);
ReleaseDC(NULL, hDC);
if (hNewDIB)
/* Unlock the new DIB's memory block */
GlobalUnlock(hNewDIB);
DeleteObject(hBitmap);
DeleteObject(hPal);
return hNewDIB;
}
/*************************************************************************
*
* ChangeBitmapFormat()
*
* Parameter:
*
* HBITMAP - handle to a bitmap
*
* WORD - desired bits per pixel
*
* DWORD - desired compression format
*
* HPALETTE - handle to palette
*
* Return Value:
*
* HDIB - handle to the new DIB if successful, else NULL
*
* Description:
*
* This function will convert a bitmap to the specified bits per pixel
* and compression format. The bitmap and it's palette will remain
* after calling this function.
*
* History:
*
* Date Author Reason
* 6/01/91 Garrett McAuliffe Created
* 12/10/91 Patrick Schreiber Modified from converting RGB to RLE8
* to converting RGB/RLE to RGB/RLE.
* Added wBitCount and dwCompression
* parameters. Also added header and
* comments.
* 12/11/91 Patrick Schreiber Destroy old DIB if conversion was
* successful.
* 12/16/91 Patrick Schreiber Modified from converting DIB to new
* DIB to bitmap to new DIB. Added palette
* parameter.
*
************************************************************************/
HDIB FAR ChangeBitmapFormat(HBITMAP hBitmap,
WORD wBitCount,
DWORD dwCompression,
HPALETTE hPal)
{
HDC hDC; // Screen DC
HDIB hNewDIB=NULL; // Handle to new DIB
BITMAP Bitmap; // BITMAP data structure
BITMAPINFOHEADER bi; // Bitmap info. header
LPBITMAPINFOHEADER lpbi; // Pointer to bitmap header
HPALETTE hOldPal=NULL; // Handle to palette
WORD NewBPP; // New bits per pixel
DWORD NewComp; // New compression format
/* Check for a valid bitmap handle */
if (!hBitmap)
return NULL;
/* Validate wBitCount and dwCompression
* They must match correctly (i.e., BI_RLE4 and 4 BPP or
* BI_RLE8 and 8BPP, etc.) or we return failure
*/
if (wBitCount == 0)
{
NewComp = dwCompression;
if (NewComp == BI_RLE4)
NewBPP = 4;
else if (NewComp == BI_RLE8)
NewBPP = 8;
else /* Not enough info */
return NULL;
}
else if (wBitCount == 1 && dwCompression == BI_RGB)
{
NewBPP = wBitCount;
NewComp = BI_RGB;
}
else if (wBitCount == 4)
{
NewBPP = wBitCount;
if (dwCompression == BI_RGB || dwCompression == BI_RLE4)
NewComp = dwCompression;
else
return NULL;
}
else if (wBitCount == 8)
{
NewBPP = wBitCount;
if (dwCompression == BI_RGB || dwCompression == BI_RLE8)
NewComp = dwCompression;
else
return NULL;
}
else if (wBitCount == 24 && dwCompression == BI_RGB)
{
NewBPP = wBitCount;
NewComp = BI_RGB;
}
else
return NULL;
/* Get info about the bitmap */
GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap);
/* Fill in the BITMAPINFOHEADER appropriately */
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = Bitmap.bmWidth;
bi.biHeight = Bitmap.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = NewBPP;
bi.biCompression = NewComp;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
/* Go allocate room for the new DIB */
hNewDIB = AllocRoomForDIB(bi, hBitmap);
if (!hNewDIB)
return NULL;
/* Get a pointer to the new DIB */
lpbi = (VOID FAR *)GlobalLock(hNewDIB);
/* If we have a palette, get a DC and select/realize it */
if (hPal)
{
hDC = GetDC(NULL);
hOldPal = SelectPalette(hDC, hPal, FALSE);
RealizePalette(hDC);
}
/* Call GetDIBits and get the new DIB bits */
if (!GetDIBits(hDC, hBitmap, 0, (WORD) lpbi->biHeight,
(LPSTR)lpbi + (WORD)lpbi->biSize + PaletteSize((LPSTR)lpbi),
(LPBITMAPINFO)lpbi, DIB_RGB_COLORS))
{
GlobalUnlock(hNewDIB);
GlobalFree(hNewDIB);
hNewDIB = NULL;
}
/* Clean up and return */
if (hOldPal)
{
SelectPalette(hDC, hOldPal, TRUE);
RealizePalette(hDC);
ReleaseDC(NULL, hDC);
}
if (hNewDIB)
{
/* Unlock the new DIB's memory block */
GlobalUnlock(hNewDIB);
}
return hNewDIB;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -