📄 dibobj.c
字号:
Info->bmiHeader.biHeight = BitmapObj->SurfObj.sizlBitmap.cy;
/* Report negtive height for top-down bitmaps. */
if (BitmapObj->SurfObj.lDelta > 0)
Info->bmiHeader.biHeight = -Info->bmiHeader.biHeight;
Info->bmiHeader.biPlanes = 1;
Info->bmiHeader.biBitCount = BitsPerFormat(BitmapObj->SurfObj.iBitmapFormat);
if (Info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
{
switch (BitmapObj->SurfObj.iBitmapFormat)
{
case BMF_1BPP: case BMF_4BPP: case BMF_8BPP:
case BMF_16BPP: case BMF_24BPP: case BMF_32BPP:
Info->bmiHeader.biCompression = BI_RGB;
break;
case BMF_4RLE:
Info->bmiHeader.biCompression = BI_RLE4;
break;
case BMF_8RLE:
Info->bmiHeader.biCompression = BI_RLE8;
break;
case BMF_JPEG:
Info->bmiHeader.biCompression = BI_JPEG;
break;
case BMF_PNG:
Info->bmiHeader.biCompression = BI_PNG;
break;
}
Info->bmiHeader.biSizeImage = BitmapObj->SurfObj.cjBits;
Info->bmiHeader.biXPelsPerMeter = 0; /* FIXME */
Info->bmiHeader.biYPelsPerMeter = 0; /* FIXME */
Info->bmiHeader.biClrUsed =
Info->bmiHeader.biClrImportant = 1 << Info->bmiHeader.biBitCount; /* FIXME */
Result = BitmapObj->SurfObj.sizlBitmap.cy;
}
}
}
else
{
if (StartScan > BitmapObj->SurfObj.sizlBitmap.cy)
{
Result = 0;
}
else
{
ScanLines = min(ScanLines, BitmapObj->SurfObj.sizlBitmap.cy - StartScan);
DestSize.cx = BitmapObj->SurfObj.sizlBitmap.cx;
DestSize.cy = ScanLines;
DestBitmap = NULL;
if (Info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
{
DestBitmap = EngCreateBitmap(DestSize,
/* DIB_GetDIBWidthBytes(DestSize.cx, Info->bmiHeader.biBitCount), */
DestSize.cx * (Info->bmiHeader.biBitCount >> 3), /* HACK */
BitmapFormat(Info->bmiHeader.biBitCount, Info->bmiHeader.biCompression),
0 < Info->bmiHeader.biHeight ? 0 : BMF_TOPDOWN,
Bits);
}
if (Info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
{
BITMAPCOREHEADER* coreheader = (BITMAPCOREHEADER*) Info;
DestBitmap = EngCreateBitmap(DestSize,
DIB_GetDIBWidthBytes(DestSize.cx, coreheader->bcBitCount),
BitmapFormat(coreheader->bcBitCount, BI_RGB),
0 < coreheader->bcHeight ? 0 : BMF_TOPDOWN,
Bits);
}
if(DestBitmap == NULL)
{
BITMAPOBJ_UnlockBitmap(BitmapObj);
return 0;
}
DestSurfObj = EngLockSurface((HSURF)DestBitmap);
SourcePalette = PALETTE_LockPalette(hSourcePalette);
/* FIXME - SourcePalette can be NULL!!! Don't assert here! */
ASSERT(SourcePalette);
SourcePaletteType = SourcePalette->Mode;
PALETTE_UnlockPalette(SourcePalette);
DestPalette = PALETTE_LockPalette(hDestPalette);
/* FIXME - DestPalette can be NULL!!!! Don't assert here!!! */
ASSERT(DestPalette);
DestPaletteType = DestPalette->Mode;
/* Copy palette. */
/* FIXME: This is largely incomplete. */
if (Info->bmiHeader.biBitCount <= 8)
{
if (Usage == DIB_RGB_COLORS)
{
for (Index = 0;
Index < (1 << Info->bmiHeader.biBitCount) &&
Index < DestPalette->NumColors;
Index++)
{
Info->bmiColors[Index].rgbRed =
DestPalette->IndexedColors[Index].peRed;
Info->bmiColors[Index].rgbGreen =
DestPalette->IndexedColors[Index].peGreen;
Info->bmiColors[Index].rgbBlue =
DestPalette->IndexedColors[Index].peBlue;
}
}
if (Usage == DIB_PAL_COLORS)
{
DPRINT1("GetDIBits with DIB_PAL_COLORS isn't implemented yet.");
}
}
PALETTE_UnlockPalette(DestPalette);
XlateObj = IntEngCreateXlate(
DestPaletteType, SourcePaletteType, hDestPalette, hSourcePalette);
SourcePoint.x = 0;
SourcePoint.y = BitmapObj->SurfObj.sizlBitmap.cy -
(StartScan + ScanLines);
/* Determine destination rectangle */
DestRect.top = 0;
DestRect.left = 0;
DestRect.right = DestSize.cx;
DestRect.bottom = DestSize.cy;
if (EngCopyBits(DestSurfObj, &BitmapObj->SurfObj,
NULL, XlateObj, &DestRect, &SourcePoint))
{
Result = ScanLines;
}
EngDeleteXlate(XlateObj);
EngUnlockSurface(DestSurfObj);
}
}
BITMAPOBJ_UnlockBitmap(BitmapObj);
return Result;
}
INT STDCALL NtGdiStretchDIBits(HDC hDC,
INT XDest,
INT YDest,
INT DestWidth,
INT DestHeight,
INT XSrc,
INT YSrc,
INT SrcWidth,
INT SrcHeight,
CONST VOID *Bits,
CONST BITMAPINFO *BitsInfo,
UINT Usage,
DWORD ROP)
{
HBITMAP hBitmap, hOldBitmap;
HDC hdcMem;
HPALETTE hPal = NULL;
if (!Bits || !BitsInfo)
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return 0;
}
hdcMem = NtGdiCreateCompatibleDC(hDC);
hBitmap = NtGdiCreateCompatibleBitmap(hDC, BitsInfo->bmiHeader.biWidth,
BitsInfo->bmiHeader.biHeight);
hOldBitmap = NtGdiSelectObject(hdcMem, hBitmap);
if(Usage == DIB_PAL_COLORS)
{
hPal = NtGdiGetCurrentObject(hDC, OBJ_PAL);
hPal = NtUserSelectPalette(hdcMem, hPal, FALSE);
}
if (BitsInfo->bmiHeader.biCompression == BI_RLE4 ||
BitsInfo->bmiHeader.biCompression == BI_RLE8)
{
/* copy existing bitmap from destination dc */
if (SrcWidth == DestWidth && SrcHeight == DestHeight)
NtGdiBitBlt(hdcMem, XSrc, abs(BitsInfo->bmiHeader.biHeight) - SrcHeight - YSrc,
SrcWidth, SrcHeight, hDC, XDest, YDest, ROP, 0, 0);
else
NtGdiStretchBlt(hdcMem, XSrc, abs(BitsInfo->bmiHeader.biHeight) - SrcHeight - YSrc,
SrcWidth, SrcHeight, hDC, XDest, YDest, DestWidth, DestHeight,
ROP, 0);
}
NtGdiSetDIBits(hdcMem, hBitmap, 0, BitsInfo->bmiHeader.biHeight, Bits,
BitsInfo, Usage);
/* Origin for DIBitmap may be bottom left (positive biHeight) or top
left (negative biHeight) */
if (SrcWidth == DestWidth && SrcHeight == DestHeight)
NtGdiBitBlt(hDC, XDest, YDest, DestWidth, DestHeight,
hdcMem, XSrc, abs(BitsInfo->bmiHeader.biHeight) - SrcHeight - YSrc,
ROP, 0, 0);
else
NtGdiStretchBlt(hDC, XDest, YDest, DestWidth, DestHeight,
hdcMem, XSrc, abs(BitsInfo->bmiHeader.biHeight) - SrcHeight - YSrc,
SrcWidth, SrcHeight, ROP, 0);
if(hPal)
NtUserSelectPalette(hdcMem, hPal, FALSE);
NtGdiSelectObject(hdcMem, hOldBitmap);
NtGdiDeleteObjectApp(hdcMem);
NtGdiDeleteObject(hBitmap);
return SrcHeight;
}
HBITMAP FASTCALL
IntCreateDIBitmap(PDC Dc, const BITMAPINFOHEADER *header,
DWORD init, LPCVOID bits, const BITMAPINFO *data,
UINT coloruse)
{
HBITMAP handle;
LONG width;
LONG height;
WORD planes;
WORD bpp;
LONG compr;
LONG dibsize;
BOOL fColor;
SIZEL size;
if (DIB_GetBitmapInfo( header, &width, &height, &planes, &bpp, &compr, &dibsize ) == -1) return 0;
// Check if we should create a monochrome or color bitmap. We create a monochrome bitmap only if it has exactly 2
// colors, which are black followed by white, nothing else. In all other cases, we create a color bitmap.
if (bpp != 1) fColor = TRUE;
else if ((coloruse != DIB_RGB_COLORS) ||
(init != CBM_INIT) || !data) fColor = FALSE;
else
{
if (data->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
{
const RGBQUAD *rgb = data->bmiColors;
DWORD col = RGB( rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue );
// Check if the first color of the colormap is black
if ((col == RGB(0, 0, 0)))
{
rgb++;
col = RGB( rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue );
// If the second color is white, create a monochrome bitmap
fColor = (col != RGB(0xff,0xff,0xff));
}
else fColor = TRUE;
}
else if (data->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
{
RGBTRIPLE *rgb = ((BITMAPCOREINFO *)data)->bmciColors;
DWORD col = RGB( rgb->rgbtRed, rgb->rgbtGreen, rgb->rgbtBlue);
if ((col == RGB(0,0,0)))
{
rgb++;
col = RGB( rgb->rgbtRed, rgb->rgbtGreen, rgb->rgbtBlue );
fColor = (col != RGB(0xff,0xff,0xff));
}
else fColor = TRUE;
}
else
{
DPRINT("(%ld): wrong size for data\n", data->bmiHeader.biSize );
return 0;
}
}
// Now create the bitmap
if (fColor)
{
handle = IntCreateCompatibleBitmap(Dc, width, height);
}
else
{
size.cx = width;
size.cy = abs(height);
handle = IntCreateBitmap(size, DIB_GetDIBWidthBytes(width, 1), BMF_1BPP,
(height < 0 ? BMF_TOPDOWN : 0) | BMF_NOZEROINIT,
NULL);
}
if (height < 0)
height = -height;
if (NULL != handle && CBM_INIT == init)
{
IntSetDIBits(Dc, handle, 0, height, bits, data, coloruse);
}
return handle;
}
// The CreateDIBitmap function creates a device-dependent bitmap (DDB) from a DIB and, optionally, sets the bitmap bits
// The DDB that is created will be whatever bit depth your reference DC is
HBITMAP STDCALL NtGdiCreateDIBitmap(HDC hDc, const BITMAPINFOHEADER *Header,
DWORD Init, LPCVOID Bits, const BITMAPINFO *Data,
UINT ColorUse)
{
PDC Dc;
HBITMAP Bmp;
if (Header == NULL)
{
return NULL;
}
if (Header->biSize == 0)
{
return NULL;
}
if (NULL == hDc)
{
BITMAPINFOHEADER *change_Header = (BITMAPINFOHEADER *)Header;
hDc = IntGdiCreateDC(NULL, NULL, NULL, NULL,FALSE);
if (hDc == NULL)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return NULL;
}
Dc = DC_LockDc(hDc);
if (Dc == NULL)
{
NtGdiDeleteObjectApp(hDc);
SetLastWin32Error(ERROR_INVALID_HANDLE);
return NULL;
}
change_Header->biBitCount = 1;
change_Header->biPlanes = 1;
Bmp = IntCreateDIBitmap(Dc, Header, Init, Bits, Data, ColorUse);
DC_UnlockDc(Dc);
NtGdiDeleteObjectApp(hDc);
}
else
{
Dc = DC_LockDc(hDc);
if (Dc == NULL)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return NULL;
}
Bmp = IntCreateDIBitmap(Dc, Header, Init, Bits, Data, ColorUse);
DC_UnlockDc(Dc);
}
return Bmp;
}
HBITMAP STDCALL NtGdiCreateDIBSection(HDC hDC,
IN OPTIONAL HANDLE hSection,
IN DWORD dwOffset,
IN LPBITMAPINFO bmi,
DWORD Usage,
IN UINT cjHeader,
IN FLONG fl,
IN ULONG_PTR dwColorSpace,
PVOID *Bits)
{
HBITMAP hbitmap = 0;
DC *dc;
BOOL bDesktopDC = FALSE;
// If the reference hdc is null, take the desktop dc
if (hDC == 0)
{
hDC = NtGdiCreateCompatibleDC(0);
bDesktopDC = TRUE;
}
if ((dc = DC_LockDc(hDC)))
{
hbitmap = DIB_CreateDIBSection ( dc, (BITMAPINFO*)bmi, Usage, Bits,
hSection, dwOffset, 0);
DC_UnlockDc(dc);
}
else
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
}
if (bDesktopDC)
NtGdiDeleteObjectApp(hDC);
return hbitmap;
}
HBITMAP STDCALL
DIB_CreateDIBSection(
PDC dc, BITMAPINFO *bmi, UINT usage,
LPVOID *bits, HANDLE section,
DWORD offset, DWORD ovr_pitch)
{
HBITMAP res = 0;
BITMAPOBJ *bmp = NULL;
DIBSECTION *dib = NULL;
// Fill BITMAP32 structure with DIB data
BITMAPINFOHEADER *bi = &bmi->bmiHeader;
INT effHeight;
ULONG totalSize;
UINT Entries = 0;
BITMAP bm;
SIZEL Size;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -