📄 dibutils.cpp
字号:
}
nNumColors = DibNumColors(&bi);
#if 0
if (bi.biSizeImage == 0)
bi.biSizeImage = DibSizeImage(&bi);
if (bi.biClrUsed == 0)
bi.biClrUsed = DibNumColors(&bi);
#else
FixBitmapInfo(&bi);
#endif
pdib = (PDIB)GlobalAllocPtr(GMEM_MOVEABLE,(LONG)bi.biSize + nNumColors * sizeof(RGBQUAD));
if (!pdib)
return NULL;
*pdib = bi;
pRgb = DibColors(pdib);
if (nNumColors)
{
if (size == sizeof(BITMAPCOREHEADER))
{
/*
* convert a old color table (3 byte entries) to a new
* color table (4 byte entries)
*/
_lread(fh,(LPVOID)pRgb,nNumColors * sizeof(RGBTRIPLE));
for (i=nNumColors-1; i>=0; i--)
{
RGBQUAD rgb;
rgb.rgbRed = ((RGBTRIPLE FAR *)pRgb)[i].rgbtRed;
rgb.rgbBlue = ((RGBTRIPLE FAR *)pRgb)[i].rgbtBlue;
rgb.rgbGreen = ((RGBTRIPLE FAR *)pRgb)[i].rgbtGreen;
rgb.rgbReserved = (BYTE)0;
pRgb[i] = rgb;
}
}
else
{
_lread(fh,(LPVOID)pRgb,nNumColors * sizeof(RGBQUAD));
}
}
if (bf.bfOffBits != 0L)
_llseek(fh,off + bf.bfOffBits,SEEK_SET);
return pdib;
}
/*
* DibSetUsage(hdib,hpal,wUsage)
*
* Modifies the color table of the passed DIB for use with the wUsage
* parameter specifed.
*
* if wUsage is DIB_PAL_COLORS the DIB color table is set to 0-256
* if wUsage is DIB_RGB_COLORS the DIB color table is set to the RGB values
* in the passed palette
*/
BOOL DibSetUsage(PDIB pdib, HPALETTE hpal,UINT wUsage)
{
PALETTEENTRY ape[256];
RGBQUAD FAR * pRgb;
WORD FAR * pw;
int nColors;
int n;
if (hpal == NULL)
hpal = (HPALETTE)GetStockObject(DEFAULT_PALETTE);
if (!pdib)
return FALSE;
nColors = DibNumColors(pdib);
if (nColors == 3 && DibCompression(pdib) == BI_BITFIELDS)
nColors = 0;
if (nColors > 0)
{
pRgb = DibColors(pdib);
switch (wUsage)
{
//
// Set the DIB color table to palette indexes
//
case DIB_PAL_COLORS:
for (pw = (WORD FAR*)pRgb,n=0; n<nColors; n++,pw++)
*pw = n;
break;
//
// Set the DIB color table to RGBQUADS
//
default:
case DIB_RGB_COLORS:
nColors = (nColors < 256) ? nColors: 256;
GetPaletteEntries(hpal,0,nColors,ape);
for (n=0; n<nColors; n++)
{
pRgb[n].rgbRed = ape[n].peRed;
pRgb[n].rgbGreen = ape[n].peGreen;
pRgb[n].rgbBlue = ape[n].peBlue;
pRgb[n].rgbReserved = 0;
}
break;
}
}
return TRUE;
}
/*
* DibCreate(bits, dx, dy)
*
* Creates a new packed DIB with the given dimensions and the
* given number of bits per pixel
*/
PDIB DibCreate(int bits, int dx, int dy)
{
LPBITMAPINFOHEADER lpbi ;
DWORD dwSizeImage;
int i;
DWORD FAR *pdw;
dwSizeImage = dy*(DWORD)((dx*bits/8+3)&~3);
lpbi = (PDIB)GlobalAllocPtr(GHND,sizeof(BITMAPINFOHEADER)+dwSizeImage + 1024);
if (lpbi == NULL)
return NULL;
lpbi->biSize = sizeof(BITMAPINFOHEADER) ;
lpbi->biWidth = dx;
lpbi->biHeight = dy;
lpbi->biPlanes = 1;
lpbi->biBitCount = bits ;
lpbi->biCompression = BI_RGB ;
lpbi->biSizeImage = dwSizeImage;
lpbi->biXPelsPerMeter = 0 ;
lpbi->biYPelsPerMeter = 0 ;
lpbi->biClrUsed = 0 ;
lpbi->biClrImportant = 0 ;
if (bits == 4)
lpbi->biClrUsed = 16;
else if (bits == 8)
lpbi->biClrUsed = 256;
pdw = (DWORD FAR *)((LPBYTE)lpbi+(int)lpbi->biSize);
for (i=0; i<(int)lpbi->biClrUsed/16; i++)
{
*pdw++ = 0x00000000; // 0000 black
*pdw++ = 0x00800000; // 0001 dark red
*pdw++ = 0x00008000; // 0010 dark green
*pdw++ = 0x00808000; // 0011 mustard
*pdw++ = 0x00000080; // 0100 dark blue
*pdw++ = 0x00800080; // 0101 purple
*pdw++ = 0x00008080; // 0110 dark turquoise
*pdw++ = 0x00C0C0C0; // 1000 gray
*pdw++ = 0x00808080; // 0111 dark gray
*pdw++ = 0x00FF0000; // 1001 red
*pdw++ = 0x0000FF00; // 1010 green
*pdw++ = 0x00FFFF00; // 1011 yellow
*pdw++ = 0x000000FF; // 1100 blue
*pdw++ = 0x00FF00FF; // 1101 pink (magenta)
*pdw++ = 0x0000FFFF; // 1110 cyan
*pdw++ = 0x00FFFFFF; // 1111 white
}
return (PDIB)lpbi;
}
static void xlatClut8(BYTE FAR *pb, DWORD dwSize, BYTE FAR *xlat)
{
DWORD dw;
#ifdef __cplusplus
for (dw = 0; dw < dwSize; dw++, ((BYTE _huge *&)pb)++)
#else
for (dw = 0; dw < dwSize; dw++, ((BYTE _huge *)pb)++)
#endif
*pb = xlat[*pb];
}
static void xlatClut4(BYTE FAR *pb, DWORD dwSize, BYTE FAR *xlat)
{
DWORD dw;
#ifdef __cplusplus
for (dw = 0; dw < dwSize; dw++, ((BYTE _huge *&)pb)++)
#else
for (dw = 0; dw < dwSize; dw++, ((BYTE _huge *)pb)++)
#endif
*pb = (BYTE)(xlat[*pb & 0x0F] | (xlat[(*pb >> 4) & 0x0F] << 4));
}
#define RLE_ESCAPE 0
#define RLE_EOL 0
#define RLE_EOF 1
#define RLE_JMP 2
static void xlatRle8(BYTE FAR *pb, DWORD dwSize, BYTE FAR *xlat)
{
BYTE cnt;
BYTE b;
BYTE _huge *prle = pb;
for(;;)
{
cnt = *prle++;
b = *prle;
if (cnt == RLE_ESCAPE)
{
prle++;
switch (b)
{
case RLE_EOF:
return;
case RLE_EOL:
break;
case RLE_JMP:
prle++; // skip dX
prle++; // skip dY
break;
default:
cnt = b;
for (b=0; b<cnt; b++,prle++)
*prle = xlat[*prle];
if (cnt & 1)
prle++;
break;
}
}
else
{
*prle++ = xlat[b];
}
}
}
static void xlatRle4(BYTE FAR *pb, DWORD dwSize, BYTE FAR *xlat)
{
}
static void hmemmove(BYTE _huge *d, BYTE _huge *s, LONG len)
{
d += len-1;
s += len-1;
while (len--)
*d-- = *s--;
}
/*
* DibMapToPalette(pdib, hpal)
*
* Map the colors of the DIB, using GetNearestPaletteIndex, to
* the colors of the given palette.
*/
BOOL DibMapToPalette(PDIB pdib, HPALETTE hpal)
{
LPBITMAPINFOHEADER lpbi;
PALETTEENTRY pe;
int n;
int nDibColors;
int nPalColors=0;
BYTE FAR * lpBits;
RGBQUAD FAR * lpRgb;
BYTE xlat[256];
DWORD SizeImage;
if (!hpal || !pdib)
return FALSE;
lpbi = (LPBITMAPINFOHEADER)pdib;
lpRgb = DibColors(pdib);
GetObject(hpal,sizeof(int),(LPSTR)&nPalColors);
nDibColors = DibNumColors(pdib);
if ((SizeImage = lpbi->biSizeImage) == 0)
SizeImage = DibSizeImage(lpbi);
//
// build a xlat table. from the current DIB colors to the given
// palette.
//
for (n=0; n<nDibColors; n++)
xlat[n] = (BYTE)GetNearestPaletteIndex(hpal,RGB(lpRgb[n].rgbRed,lpRgb[n].rgbGreen,lpRgb[n].rgbBlue));
lpBits = (LPBYTE)DibPtr(lpbi);
lpbi->biClrUsed = nPalColors;
//
// re-size the DIB
//
if (nPalColors > nDibColors)
{
GlobalReAllocPtr(lpbi, lpbi->biSize + nPalColors*sizeof(RGBQUAD) + SizeImage, 0);
hmemmove((BYTE _huge *)DibPtr(lpbi), (BYTE _huge *)lpBits, SizeImage);
lpBits = (LPBYTE)DibPtr(lpbi);
}
else if (nPalColors < nDibColors)
{
hmemcpy(DibPtr(lpbi), lpBits, SizeImage);
GlobalReAllocPtr(lpbi, lpbi->biSize + nPalColors*sizeof(RGBQUAD) + SizeImage, 0);
lpBits = (LPBYTE)DibPtr(lpbi);
}
//
// translate the DIB bits
//
switch (lpbi->biCompression)
{
case BI_RLE8:
xlatRle8(lpBits, SizeImage, xlat);
break;
case BI_RLE4:
xlatRle4(lpBits, SizeImage, xlat);
break;
case BI_RGB:
if (lpbi->biBitCount == 8)
xlatClut8(lpBits, SizeImage, xlat);
else
xlatClut4(lpBits, SizeImage, xlat);
break;
}
//
// Now copy the RGBs in the logical palette to the dib color table
//
for (n=0; n<nPalColors; n++)
{
GetPaletteEntries(hpal,n,1,&pe);
lpRgb[n].rgbRed = pe.peRed;
lpRgb[n].rgbGreen = pe.peGreen;
lpRgb[n].rgbBlue = pe.peBlue;
lpRgb[n].rgbReserved = (BYTE)0;
}
return TRUE;
}
HPALETTE MakePalette(const BITMAPINFO FAR* Info, UINT flags)
{
HPALETTE hPalette;
const RGBQUAD far* rgb = Info->bmiColors;
WORD nColors = Info->bmiHeader.biClrUsed;
if (nColors) {
LOGPALETTE* logPal = (LOGPALETTE*)
new BYTE[sizeof(LOGPALETTE) + (nColors-1)*sizeof(PALETTEENTRY)];
logPal->palVersion = 0x300; // Windows 3.0 version
logPal->palNumEntries = nColors;
for (short n = 0; n < nColors; n++) {
logPal->palPalEntry[n].peRed = rgb[n].rgbRed;
logPal->palPalEntry[n].peGreen = rgb[n].rgbGreen;
logPal->palPalEntry[n].peBlue = rgb[n].rgbBlue;
logPal->palPalEntry[n].peFlags = (BYTE)flags;
}
hPalette = ::CreatePalette(logPal);
delete logPal;
} else
hPalette = 0;
return hPalette;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -