📄 dibobj.c
字号:
/*
* $Id: dibobj.c 24578 2006-10-20 13:19:13Z weiden $
*
* ReactOS W32 Subsystem
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <w32k.h>
#define NDEBUG
#include <debug.h>
UINT STDCALL
NtGdiSetDIBColorTable(HDC hDC, UINT StartIndex, UINT Entries, CONST RGBQUAD *Colors)
{
PDC dc;
PBITMAPOBJ BitmapObj;
PPALGDI PalGDI;
UINT Index;
if (!(dc = DC_LockDc(hDC))) return 0;
if (dc->IsIC)
{
DC_UnlockDc(dc);
return 0;
}
BitmapObj = BITMAPOBJ_LockBitmap(dc->w.hBitmap);
if (BitmapObj == NULL)
{
DC_UnlockDc(dc);
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return 0;
}
if (BitmapObj->dib == NULL)
{
BITMAPOBJ_UnlockBitmap(BitmapObj);
DC_UnlockDc(dc);
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return 0;
}
if (BitmapObj->dib->dsBmih.biBitCount <= 8 &&
StartIndex < (1 << BitmapObj->dib->dsBmih.biBitCount))
{
if (StartIndex + Entries > (1 << BitmapObj->dib->dsBmih.biBitCount))
Entries = (1 << BitmapObj->dib->dsBmih.biBitCount) - StartIndex;
PalGDI = PALETTE_LockPalette(BitmapObj->hDIBPalette);
_SEH_TRY
{
for (Index = StartIndex;
Index < StartIndex + Entries && Index < PalGDI->NumColors;
Index++)
{
PalGDI->IndexedColors[Index].peRed = Colors[Index - StartIndex].rgbRed;
PalGDI->IndexedColors[Index].peGreen = Colors[Index - StartIndex].rgbGreen;
PalGDI->IndexedColors[Index].peBlue = Colors[Index - StartIndex].rgbBlue;
}
}
_SEH_HANDLE
{
Entries = 0;
}
_SEH_END
PALETTE_UnlockPalette(PalGDI);
}
else
Entries = 0;
BITMAPOBJ_UnlockBitmap(BitmapObj);
DC_UnlockDc(dc);
return Entries;
}
UINT STDCALL
NtGdiGetDIBColorTable(HDC hDC, UINT StartIndex, UINT Entries, RGBQUAD *Colors)
{
PDC dc;
PBITMAPOBJ BitmapObj;
PPALGDI PalGDI;
UINT Index;
if (!(dc = DC_LockDc(hDC))) return 0;
if (dc->IsIC)
{
DC_UnlockDc(dc);
return 0;
}
BitmapObj = BITMAPOBJ_LockBitmap(dc->w.hBitmap);
if (BitmapObj == NULL)
{
DC_UnlockDc(dc);
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return 0;
}
if (BitmapObj->dib == NULL)
{
BITMAPOBJ_UnlockBitmap(BitmapObj);
DC_UnlockDc(dc);
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return 0;
}
if (BitmapObj->dib->dsBmih.biBitCount <= 8 &&
StartIndex < (1 << BitmapObj->dib->dsBmih.biBitCount))
{
if (StartIndex + Entries > (1 << BitmapObj->dib->dsBmih.biBitCount))
Entries = (1 << BitmapObj->dib->dsBmih.biBitCount) - StartIndex;
PalGDI = PALETTE_LockPalette(BitmapObj->hDIBPalette);
_SEH_TRY
{
for (Index = StartIndex;
Index < StartIndex + Entries && Index < PalGDI->NumColors;
Index++)
{
Colors[Index - StartIndex].rgbRed = PalGDI->IndexedColors[Index].peRed;
Colors[Index - StartIndex].rgbGreen = PalGDI->IndexedColors[Index].peGreen;
Colors[Index - StartIndex].rgbBlue = PalGDI->IndexedColors[Index].peBlue;
}
}
_SEH_HANDLE
{
Entries = 0;
}
_SEH_END
PALETTE_UnlockPalette(PalGDI);
}
else
Entries = 0;
BITMAPOBJ_UnlockBitmap(BitmapObj);
DC_UnlockDc(dc);
return Entries;
}
// Converts a DIB to a device-dependent bitmap
static INT FASTCALL
IntSetDIBits(
PDC DC,
HBITMAP hBitmap,
UINT StartScan,
UINT ScanLines,
CONST VOID *Bits,
CONST BITMAPINFO *bmi,
UINT ColorUse)
{
BITMAPOBJ *bitmap;
HBITMAP SourceBitmap;
INT result = 0;
BOOL copyBitsResult;
SURFOBJ *DestSurf, *SourceSurf;
SIZEL SourceSize;
POINTL ZeroPoint;
RECTL DestRect;
XLATEOBJ *XlateObj;
PPALGDI hDCPalette;
//RGBQUAD *lpRGB;
HPALETTE DDB_Palette, DIB_Palette;
ULONG DDB_Palette_Type, DIB_Palette_Type;
INT DIBWidth;
// Check parameters
if (!(bitmap = BITMAPOBJ_LockBitmap(hBitmap)))
{
return 0;
}
// Get RGB values
//if (ColorUse == DIB_PAL_COLORS)
// lpRGB = DIB_MapPaletteColors(hDC, bmi);
//else
// lpRGB = &bmi->bmiColors;
DestSurf = &bitmap->SurfObj;
// Create source surface
SourceSize.cx = bmi->bmiHeader.biWidth;
SourceSize.cy = ScanLines;
// Determine width of DIB
DIBWidth = DIB_GetDIBWidthBytes(SourceSize.cx, bmi->bmiHeader.biBitCount);
SourceBitmap = EngCreateBitmap(SourceSize,
DIBWidth,
BitmapFormat(bmi->bmiHeader.biBitCount, bmi->bmiHeader.biCompression),
bmi->bmiHeader.biHeight < 0 ? BMF_TOPDOWN : 0,
(PVOID) Bits);
if (0 == SourceBitmap)
{
BITMAPOBJ_UnlockBitmap(bitmap);
SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
return 0;
}
SourceSurf = EngLockSurface((HSURF)SourceBitmap);
if (NULL == SourceSurf)
{
EngDeleteSurface((HSURF)SourceBitmap);
BITMAPOBJ_UnlockBitmap(bitmap);
SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
return 0;
}
// Destination palette obtained from the hDC
hDCPalette = PALETTE_LockPalette(DC->DevInfo->hpalDefault);
if (NULL == hDCPalette)
{
EngUnlockSurface(SourceSurf);
EngDeleteSurface((HSURF)SourceBitmap);
BITMAPOBJ_UnlockBitmap(bitmap);
SetLastWin32Error(ERROR_INVALID_HANDLE);
return 0;
}
DDB_Palette_Type = hDCPalette->Mode;
DDB_Palette = DC->DevInfo->hpalDefault;
PALETTE_UnlockPalette(hDCPalette);
// Source palette obtained from the BITMAPINFO
DIB_Palette = BuildDIBPalette ( (PBITMAPINFO)bmi, (PINT)&DIB_Palette_Type );
if (NULL == DIB_Palette)
{
EngUnlockSurface(SourceSurf);
EngDeleteSurface((HSURF)SourceBitmap);
BITMAPOBJ_UnlockBitmap(bitmap);
SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
return 0;
}
// Determine XLATEOBJ for color translation
XlateObj = IntEngCreateXlate(DDB_Palette_Type, DIB_Palette_Type, DDB_Palette, DIB_Palette);
if (NULL == XlateObj)
{
PALETTE_FreePalette(DIB_Palette);
EngUnlockSurface(SourceSurf);
EngDeleteSurface((HSURF)SourceBitmap);
BITMAPOBJ_UnlockBitmap(bitmap);
SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
return 0;
}
// Zero point
ZeroPoint.x = 0;
ZeroPoint.y = 0;
// Determine destination rectangle
DestRect.left = 0;
DestRect.top = abs(bmi->bmiHeader.biHeight) - StartScan - ScanLines;
DestRect.right = SourceSize.cx;
DestRect.bottom = DestRect.top + ScanLines;
copyBitsResult = EngCopyBits(DestSurf, SourceSurf, NULL, XlateObj, &DestRect, &ZeroPoint);
// If it succeeded, return number of scanlines copies
if(copyBitsResult == TRUE)
{
result = SourceSize.cy - 1;
}
// Clean up
EngDeleteXlate(XlateObj);
PALETTE_FreePalette(DIB_Palette);
EngUnlockSurface(SourceSurf);
EngDeleteSurface((HSURF)SourceBitmap);
// if (ColorUse == DIB_PAL_COLORS)
// WinFree((LPSTR)lpRGB);
BITMAPOBJ_UnlockBitmap(bitmap);
return result;
}
// Converts a DIB to a device-dependent bitmap
INT STDCALL
NtGdiSetDIBits(
HDC hDC,
HBITMAP hBitmap,
UINT StartScan,
UINT ScanLines,
CONST VOID *Bits,
CONST BITMAPINFO *bmi,
UINT ColorUse)
{
PDC Dc;
INT Ret;
Dc = DC_LockDc(hDC);
if (NULL == Dc)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return 0;
}
if (Dc->IsIC)
{
DC_UnlockDc(Dc);
return 0;
}
Ret = IntSetDIBits(Dc, hBitmap, StartScan, ScanLines, Bits, bmi, ColorUse);
DC_UnlockDc(Dc);
return Ret;
}
INT STDCALL
NtGdiSetDIBitsToDevice(
HDC hDC,
INT XDest,
INT YDest,
DWORD Width,
DWORD Height,
INT XSrc,
INT YSrc,
UINT StartScan,
UINT ScanLines,
CONST VOID *Bits,
CONST BITMAPINFO *bmi,
UINT ColorUse)
{
UNIMPLEMENTED;
return 0;
}
/* Converts a device-dependent bitmap to a DIB */
INT STDCALL
NtGdiGetDIBits(HDC hDC,
HBITMAP hBitmap,
UINT StartScan,
UINT ScanLines,
LPVOID Bits,
LPBITMAPINFO Info,
UINT Usage)
{
BITMAPOBJ *BitmapObj;
SURFOBJ *DestSurfObj;
XLATEOBJ *XlateObj;
HBITMAP DestBitmap;
SIZEL DestSize;
HPALETTE hSourcePalette;
HPALETTE hDestPalette;
PPALGDI SourcePalette;
PPALGDI DestPalette;
ULONG SourcePaletteType;
ULONG DestPaletteType;
PDC Dc;
POINTL SourcePoint;
RECTL DestRect;
ULONG Result = 0;
ULONG Index;
/* Get handle for the palette in DC. */
Dc = DC_LockDc(hDC);
if (Dc == NULL)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return 0;
}
if (Dc->IsIC)
{
DC_UnlockDc(Dc);
return 0;
}
hSourcePalette = Dc->w.hPalette;
/* FIXME: This is incorrect. hDestPalette should be something other. */
hDestPalette = Dc->DevInfo->hpalDefault;
DC_UnlockDc(Dc);
/* Get pointer to the source bitmap object. */
BitmapObj = BITMAPOBJ_LockBitmap(hBitmap);
if (BitmapObj == NULL)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return 0;
}
if (Bits == NULL)
{
if (Info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
{
BITMAPCOREHEADER* coreheader = (BITMAPCOREHEADER*) Info;
coreheader->bcWidth =BitmapObj->SurfObj.sizlBitmap.cx;
coreheader->bcPlanes = 1;
coreheader->bcBitCount = BitsPerFormat(BitmapObj->SurfObj.iBitmapFormat);
coreheader->bcHeight = BitmapObj->SurfObj.sizlBitmap.cy;
if (BitmapObj->SurfObj.lDelta > 0)
coreheader->bcHeight = -coreheader->bcHeight;
Result = BitmapObj->SurfObj.sizlBitmap.cy;
}
if (Info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
{
Info->bmiHeader.biWidth = BitmapObj->SurfObj.sizlBitmap.cx;
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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -