📄 dib.cpp
字号:
/**************************************************************************
*
* THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
* KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
* PURPOSE.
*
* Copyright (C) 1992 - 1996 Microsoft Corporation. All Rights Reserved.
*
**************************************************************************/
#define STRICT
#include <windows.h>
#include <windowsx.h>
#include "dib.h"
#define SEEK_CUR 1 /* flags for _lseek */
#define SEEK_SET 0 /* flags for _lseek */
#define BFT_BITMAP 0x4d42 /* 'BM' */
/*----------------------------------------------------------------------------*\
| Macros |
\*----------------------------------------------------------------------------*/
#define ISDIB(bft) ((bft) == BFT_BITMAP)
#define WIDTHBYTES(i) ((unsigned)((i+31)&(~31))/8) /* ULONG aligned ! */
#define DibWidthBytesN(lpbi, n) (UINT)WIDTHBYTES((UINT)(lpbi)->biWidth * (UINT)(n))
#define DibWidthBytes(lpbi) DibWidthBytesN(lpbi, (lpbi)->biBitCount)
#define DibSize(lpbi) ((lpbi)->biSize + (lpbi)->biSizeImage + (int)(lpbi)->biClrUsed * sizeof(RGBQUAD))
#define DibSizeImage(lpbi) ((lpbi)->biSizeImage == 0 \
? ((DWORD)(UINT)DibWidthBytes(lpbi) * (DWORD)(UINT)(lpbi)->biHeight) \
: (lpbi)->biSizeImage)
#define DibNumColors(lpbi) ((lpbi)->biClrUsed == 0 && (lpbi)->biBitCount <= 8 \
? (WORD)(1 << (int)(lpbi)->biBitCount) \
: (WORD)(lpbi)->biClrUsed)
typedef RGBTRIPLE * LPRGBTRIPLE;
//----------------------------------------------------------------------------
static HDIB ReadDibBitmapInfo(int);
//----------------------------------------------------------------------------
/*
* Open a DIB file and return a MEMORY DIB, a memory handle containing..
*
* BITMAP INFO bi
* palette data
* bits....
*
*/
HDIB OpenDIB(
LPSTR szFile)
{
int fh;
LPBITMAPINFOHEADER lpbi;
DWORD dwLen;
HDIB hdib;
HANDLE h;
OFSTRUCT of;
if (HIWORD((DWORD)szFile) == 0) {
fh = LOWORD((DWORD)szFile);
} else {
fh = OpenFile(szFile, &of, OF_READ);
}
if (fh == -1)
return NULL;
hdib = ReadDibBitmapInfo(fh);
if (!hdib)
goto error;
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hdib);
//How much memory do we need to hold the DIB
dwLen = DibSize(lpbi);
//Can we get more memory?
GlobalUnlock(hdib);
h = GlobalReAlloc(hdib,dwLen,0);
if (!h) {
GlobalFree(hdib);
hdib = NULL;
} else {
hdib = h;
}
if (hdib) {
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hdib);
/* read in the bits */
_hread(fh, DibPtr(lpbi), lpbi->biSizeImage);
}
error:
if (HIWORD((DWORD)szFile) != 0)
_lclose(fh);
return hdib;
}
//----------------------------------------------------------------------------
/*
* Write a global handle in CF_DIB format to a file.
*
*/
BOOL WriteDIB(
LPSTR szFile,
HDIB hdib)
{
BITMAPFILEHEADER hdr;
LPBITMAPINFOHEADER lpbi;
int fh;
OFSTRUCT of;
if (!hdib)
return FALSE;
if (HIWORD((DWORD)szFile) == 0) {
fh = LOWORD((DWORD)szFile);
} else {
fh = OpenFile(szFile,&of,OF_CREATE|OF_READWRITE);
}
if (fh == -1)
return FALSE;
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hdib);
hdr.bfType = BFT_BITMAP;
hdr.bfSize = DibSize(lpbi) + sizeof(BITMAPFILEHEADER);
hdr.bfReserved1 = 0;
hdr.bfReserved2 = 0;
hdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) +
lpbi->biSize + lpbi->biClrUsed * sizeof(RGBQUAD);
_lwrite(fh,(LPSTR)&hdr,sizeof(BITMAPFILEHEADER));
_hwrite(fh,(LPSTR)lpbi,DibSize(lpbi));
GlobalUnlock(hdib);
if (HIWORD((DWORD)szFile) != 0)
_lclose(fh);
return TRUE;
}
//----------------------------------------------------------------------------
/*
* DibFromBitmap()
*
* Will create a global memory block in DIB format that represents the DDB
* passed in
*
*/
HDIB DibFromBitmap(
HBITMAP hbm,
DWORD biStyle,
WORD biBits,
HPALETTE hpal,
WORD wUsage)
{
BITMAP bm;
BITMAPINFOHEADER bi;
LPBITMAPINFOHEADER lpbi;
DWORD dwLen;
WORD nColors; // GetObject will only return 2 bytes
HDIB hdib;
HANDLE h;
HDC hdc;
WORD wBits;
if (!hbm)
return NULL;
if (hpal == NULL)
hpal = (HPALETTE)GetStockObject(DEFAULT_PALETTE);
GetObject(hbm,sizeof(bm),(LPSTR)&bm);
GetObject(hpal,sizeof(nColors),(LPSTR)&nColors);
if (biBits == 0)
wBits = (WORD)(bm.bmPlanes * bm.bmBitsPixel);
else
wBits = biBits;
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = bm.bmWidth;
bi.biHeight = bm.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = wBits;
bi.biCompression = biStyle;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
dwLen = bi.biSize + DibNumColors(&bi) * sizeof(RGBQUAD);
hdc = CreateCompatibleDC(NULL);
hpal = SelectPalette(hdc,hpal,FALSE);
RealizePalette(hdc); // why is this needed on a MEMORY DC? GDI bug??
hdib = GlobalAlloc(GMEM_MOVEABLE,dwLen);
if (!hdib)
goto exit;
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hdib);
*lpbi = bi;
//call GetDIBits with a NULL lpBits param, so it will calculate the
//biSizeImage field for us
GetDIBits(hdc, hbm, 0, (WORD)bi.biHeight,
NULL, (LPBITMAPINFO)lpbi, wUsage);
bi = *lpbi;
//If the driver did not fill in the biSizeImage field, fill it in
//based on the width, height and bit depth.
if (bi.biSizeImage == 0) {
bi.biSizeImage = (DWORD)WIDTHBYTES(bm.bmWidth * wBits) * bm.bmHeight;
if (biStyle != BI_RGB)
bi.biSizeImage = (bi.biSizeImage * 3) / 2;
}
//realloc the buffer big enough to hold all the bits
dwLen = bi.biSize + DibNumColors(&bi) * sizeof(RGBQUAD) + bi.biSizeImage;
if (h = GlobalReAlloc(hdib,dwLen,0)) {
hdib = h;
} else {
GlobalFree(hdib);
hdib = NULL;
goto exit;
}
//call GetDIBits with a NON-NULL lpBits param, and actualy get the
//bits this time
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hdib);
GetDIBits(hdc, hbm, 0, (WORD)bi.biHeight,
DibPtr(lpbi),(LPBITMAPINFO)lpbi, wUsage);
bi = *lpbi;
lpbi->biClrUsed = DibNumColors(lpbi);
exit:
SelectPalette(hdc,hpal,FALSE);
DeleteDC(hdc);
return hdib;
}
//----------------------------------------------------------------------------
/*
* ReadDibBitmapInfo()
*
* Will read a file in DIB format and return a global HANDLE to it's
* BITMAPINFO. This function will work with both "old" and "new"
* bitmap formats, but will allways return a "new" BITMAPINFO
*
*/
HDIB ReadDibBitmapInfo(
int fh)
{
DWORD off;
HDIB hbi = NULL;
int size;
int i;
WORD wNumColors;
LPRGBQUAD lpRgb;
BITMAPINFOHEADER bi;
BITMAPCOREHEADER bc;
LPBITMAPINFOHEADER lpbi;
BITMAPFILEHEADER bf;
if (fh == -1)
return NULL;
off = _llseek(fh,0L,SEEK_CUR);
if (sizeof(bf) != _lread(fh,(LPVOID)&bf,sizeof(bf)))
return NULL;
//do we have a RC HEADER?
if (!ISDIB(bf.bfType)) {
bf.bfOffBits = 0L;
_llseek(fh,off,SEEK_SET);
}
if (sizeof(bi) != _lread(fh,(LPVOID)&bi,sizeof(bi)))
return NULL;
wNumColors = (WORD) DibNumColors(&bi);
//what type of bitmap info is this?
switch (size = (int)bi.biSize) {
case sizeof(BITMAPCOREHEADER):
bc = *(BITMAPCOREHEADER*)&bi;
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = (DWORD)bc.bcWidth;
bi.biHeight = (DWORD)bc.bcHeight;
bi.biPlanes = (WORD)bc.bcPlanes;
bi.biBitCount = (WORD)bc.bcBitCount;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = (DWORD)(1 << bc.bcBitCount);
bi.biClrImportant = (DWORD)(1 << bc.bcBitCount);
_llseek(fh,(LONG)sizeof(BITMAPCOREHEADER)-sizeof(BITMAPINFOHEADER),SEEK_CUR);
break;
case sizeof(BITMAPINFOHEADER):
default:
break;
}
//fill in some default values!
if (bi.biSizeImage == 0)
bi.biSizeImage = DibSizeImage(&bi);
if (bi.biClrUsed == 0)
bi.biClrUsed = DibNumColors(&bi);
hbi = GlobalAlloc( GMEM_MOVEABLE, (LONG)bi.biSize + ((int)wNumColors * sizeof(RGBQUAD)) );
if (!hbi)
return NULL;
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hbi);
*lpbi = bi;
if (lpbi->biSize > sizeof(bi)) {
if (_lread(fh, (LPBYTE) lpbi + sizeof(bi), (UINT)lpbi->biSize - sizeof(bi))
!= (lpbi->biSize - sizeof(bi))) {
GlobalFree(hbi);
return NULL;
}
}
lpRgb = DibColors(lpbi);
if (wNumColors) {
if (size == sizeof(BITMAPCOREHEADER)) {
//convert a old color table (3 byte entries) to a new
//color table (4 byte entries)
_lread(fh,(LPSTR)lpRgb, ((int)wNumColors * sizeof(RGBTRIPLE)) );
for (i=(int)wNumColors-1; i>=0; i--) {
RGBQUAD rgb;
rgb.rgbRed = ((LPRGBTRIPLE)lpRgb)[i].rgbtRed;
rgb.rgbBlue = ((LPRGBTRIPLE)lpRgb)[i].rgbtBlue;
rgb.rgbGreen = ((LPRGBTRIPLE)lpRgb)[i].rgbtGreen;
rgb.rgbReserved = (BYTE)0;
lpRgb[i] = rgb;
}
} else {
_lread( fh, (LPSTR)lpRgb, ((int)wNumColors * sizeof(RGBQUAD)) );
}
}
if (bf.bfOffBits != 0L)
_llseek(fh,off + bf.bfOffBits,SEEK_SET);
GlobalUnlock(hbi);
return hbi;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -