mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 14:35:59 +00:00
[WIN32K]
- Finally get rid of ProbeAndConvertToBitmapV5Info - Rewrite renderBITMAPfromDIB, and a good bunch of DIB related functions accordingly. - Rewrite BITMAP_CopyBitmap into something simpler. - Use already existing DIB functions in IntGdiCreateDIBBrush - Use DIB sections in NtGdiStretchDIBitsInternal and NtGdiSetDIBits. - Use Bitmap hdc for NtGdiGetDIBitsInternal if there is one. svn path=/branches/reactos-yarotows/; revision=48389
This commit is contained in:
parent
147e52c02c
commit
787cb5551f
7 changed files with 264 additions and 672 deletions
|
@ -13,7 +13,6 @@ HBITMAP FASTCALL IntCreateBitmap(IN SIZEL Size, IN LONG Width, IN ULONG Format,
|
|||
HBITMAP FASTCALL BITMAP_CopyBitmap (HBITMAP hBitmap);
|
||||
UINT FASTCALL BITMAP_GetRealBitsPixel(UINT nBitsPixel);
|
||||
INT FASTCALL BITMAP_GetWidthBytes (INT bmWidth, INT bpp);
|
||||
NTSTATUS FASTCALL ProbeAndConvertToBitmapV5Info( OUT PBITMAPV5INFO pbmiDst, IN CONST BITMAPINFO* pbmiUnsafe, IN DWORD dwUse, UINT MaxSize);
|
||||
|
||||
HBITMAP
|
||||
APIENTRY
|
||||
|
@ -43,7 +42,7 @@ GreCreateDIBitmapInternal(
|
|||
IN INT cy,
|
||||
IN DWORD fInit,
|
||||
IN OPTIONAL LPBYTE pjInit,
|
||||
IN OPTIONAL PBITMAPV5INFO pbmi,
|
||||
IN OPTIONAL PBITMAPINFO pbmi,
|
||||
IN DWORD iUsage,
|
||||
IN FLONG fl,
|
||||
IN HANDLE hcmXform);
|
||||
|
|
|
@ -13,11 +13,11 @@ INT APIENTRY
|
|||
DIB_GetDIBImageBytes (INT width, INT height, INT depth);
|
||||
INT FASTCALL
|
||||
DIB_GetDIBWidthBytes (INT width, INT depth);
|
||||
RGBQUAD * FASTCALL
|
||||
DIB_MapPaletteColors(PDC dc, CONST BITMAPINFO* lpbmi);
|
||||
HPALETTE FASTCALL
|
||||
DIB_MapPaletteColors(PPALETTE ppal, CONST BITMAPINFO* lpbmi);
|
||||
|
||||
HPALETTE FASTCALL
|
||||
BuildDIBPalette (CONST BITMAPINFO *bmi, PINT paletteType);
|
||||
BuildDIBPalette (CONST BITMAPINFO *bmi);
|
||||
|
||||
BITMAPINFO* FASTCALL DIB_ConvertBitmapInfo(CONST BITMAPINFO* bmi, DWORD Usage);
|
||||
VOID FASTCALL DIB_FreeConvertedBitmapInfo(BITMAPINFO* converted, BITMAPINFO* orig);
|
|
@ -247,9 +247,11 @@ renderBITMAPfromDIB(LPBYTE pDIB)
|
|||
{
|
||||
HDC hdc;
|
||||
HBITMAP hbitmap;
|
||||
unsigned int offset = 0; /* Stupid compiler */
|
||||
BITMAPV5INFO bmi;
|
||||
PBITMAPINFO pBmi, pConvertedBmi = NULL;
|
||||
NTSTATUS Status ;
|
||||
UINT offset = 0; /* Stupid compiler */
|
||||
|
||||
pBmi = (BITMAPINFO*)pDIB;
|
||||
|
||||
//hdc = UserGetDCEx(NULL, NULL, DCX_USESTYLE);
|
||||
hdc = UserGetDCEx(ClipboardWindow, NULL, DCX_USESTYLE);
|
||||
|
@ -257,9 +259,19 @@ renderBITMAPfromDIB(LPBYTE pDIB)
|
|||
/* Probe it */
|
||||
_SEH2_TRY
|
||||
{
|
||||
Status = ProbeAndConvertToBitmapV5Info(&bmi, (BITMAPINFO*)pDIB, DIB_RGB_COLORS, 0);
|
||||
offset = DIB_BitmapInfoSize((BITMAPINFO*)pDIB, DIB_RGB_COLORS);
|
||||
ProbeForRead(pDIB + offset, bmi.bmiHeader.bV5SizeImage, 1);
|
||||
ProbeForRead(&pBmi->bmiHeader.biSize, sizeof(DWORD), 1);
|
||||
ProbeForRead(pBmi, pBmi->bmiHeader.biSize, 1);
|
||||
ProbeForRead(pBmi, DIB_BitmapInfoSize(pBmi, DIB_RGB_COLORS), 1);
|
||||
pConvertedBmi = DIB_ConvertBitmapInfo(pBmi, DIB_RGB_COLORS);
|
||||
if(!pConvertedBmi)
|
||||
{
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
else
|
||||
{
|
||||
offset = DIB_BitmapInfoSize((BITMAPINFO*)pBmi, DIB_RGB_COLORS);
|
||||
ProbeForRead(pDIB + offset, pConvertedBmi->bmiHeader.biSizeImage, 1);
|
||||
}
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
|
@ -274,17 +286,19 @@ renderBITMAPfromDIB(LPBYTE pDIB)
|
|||
}
|
||||
|
||||
hbitmap = GreCreateDIBitmapInternal(hdc,
|
||||
bmi.bmiHeader.bV5Width,
|
||||
bmi.bmiHeader.bV5Height,
|
||||
pConvertedBmi->bmiHeader.biWidth,
|
||||
pConvertedBmi->bmiHeader.biHeight,
|
||||
CBM_INIT,
|
||||
pDIB+offset,
|
||||
&bmi,
|
||||
pConvertedBmi,
|
||||
DIB_RGB_COLORS,
|
||||
0,
|
||||
0);
|
||||
//UserReleaseDC(NULL, hdc, FALSE);
|
||||
UserReleaseDC(ClipboardWindow, hdc, FALSE);
|
||||
|
||||
DIB_FreeConvertedBitmapInfo(pConvertedBmi, pBmi);
|
||||
|
||||
return hbitmap;
|
||||
}
|
||||
|
||||
|
|
|
@ -1325,12 +1325,10 @@ UserDrawIconEx(
|
|||
if(bAlpha && (diFlags & DI_IMAGE))
|
||||
{
|
||||
BLENDFUNCTION pixelblend = { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA };
|
||||
DWORD Pixel;
|
||||
BYTE Red, Green, Blue, Alpha;
|
||||
DWORD Count = 0;
|
||||
BYTE Alpha;
|
||||
INT i, j;
|
||||
PSURFACE psurf;
|
||||
PBYTE pBits ;
|
||||
PBYTE pBits, ptr ;
|
||||
HBITMAP hMemBmp = NULL;
|
||||
|
||||
pBits = ExAllocatePoolWithTag(PagedPool,
|
||||
|
@ -1363,20 +1361,15 @@ UserDrawIconEx(
|
|||
/* premultiply with the alpha channel value */
|
||||
for (i = 0; i < abs(bmpColor.bmHeight); i++)
|
||||
{
|
||||
Count = i*bmpColor.bmWidthBytes;
|
||||
ptr = pBits + i*bmpColor.bmWidthBytes;
|
||||
for (j = 0; j < bmpColor.bmWidth; j++)
|
||||
{
|
||||
Pixel = *(DWORD *)(pBits + Count);
|
||||
Alpha = ptr[3];
|
||||
ptr[0] *= Alpha / 0xff;
|
||||
ptr[1] *= Alpha / 0xff;
|
||||
ptr[2] *= Alpha / 0xff;
|
||||
|
||||
Alpha = ((BYTE)(Pixel >> 24) & 0xff);
|
||||
|
||||
Red = (((BYTE)(Pixel >> 0)) * Alpha) / 0xff;
|
||||
Green = (((BYTE)(Pixel >> 8)) * Alpha) / 0xff;
|
||||
Blue = (((BYTE)(Pixel >> 16)) * Alpha) / 0xff;
|
||||
|
||||
*(DWORD *)(pBits + Count) = (DWORD)(Red | (Green << 8) | (Blue << 16) | (Alpha << 24));
|
||||
|
||||
Count += sizeof(DWORD);
|
||||
ptr += 4;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -912,7 +912,7 @@ BITMAP_CopyBitmap(HBITMAP hBitmap)
|
|||
return 0;
|
||||
}
|
||||
|
||||
Bitmap = GDIOBJ_LockObj(hBitmap, GDI_OBJECT_TYPE_BITMAP);
|
||||
Bitmap = SURFACE_LockSurface(hBitmap);
|
||||
if (Bitmap == NULL)
|
||||
{
|
||||
return 0;
|
||||
|
@ -925,40 +925,22 @@ BITMAP_CopyBitmap(HBITMAP hBitmap)
|
|||
|
||||
Size.cx = abs(bm.bmWidth);
|
||||
Size.cy = abs(bm.bmHeight);
|
||||
res = GreCreateBitmap(abs(bm.bmWidth),
|
||||
abs(bm.bmHeight),
|
||||
1,
|
||||
bm.bmBitsPixel,
|
||||
NULL);
|
||||
res = GreCreateBitmapEx(Size.cx,
|
||||
Size.cy,
|
||||
bm.bmWidthBytes,
|
||||
Bitmap->SurfObj.iBitmapFormat,
|
||||
Bitmap->SurfObj.fjBitmap,
|
||||
Bitmap->SurfObj.cjBits,
|
||||
NULL);
|
||||
|
||||
|
||||
if (res)
|
||||
{
|
||||
PBYTE buf;
|
||||
|
||||
resBitmap = GDIOBJ_LockObj(res, GDI_OBJECT_TYPE_BITMAP);
|
||||
resBitmap = SURFACE_LockSurface(res);
|
||||
if (resBitmap)
|
||||
{
|
||||
buf = ExAllocatePoolWithTag(PagedPool,
|
||||
bm.bmWidthBytes * abs(bm.bmHeight),
|
||||
TAG_BITMAP);
|
||||
if (buf == NULL)
|
||||
{
|
||||
GDIOBJ_UnlockObjByPtr((POBJ)resBitmap);
|
||||
GDIOBJ_UnlockObjByPtr((POBJ)Bitmap);
|
||||
GreDeleteObject(res);
|
||||
return 0;
|
||||
}
|
||||
IntGetBitmapBits(Bitmap, bm.bmWidthBytes * abs(bm.bmHeight), buf);
|
||||
IntSetBitmapBits(resBitmap, bm.bmWidthBytes * abs(bm.bmHeight), buf);
|
||||
ExFreePoolWithTag(buf,TAG_BITMAP);
|
||||
resBitmap->flags = Bitmap->flags;
|
||||
/* Copy palette */
|
||||
if (Bitmap->ppal)
|
||||
{
|
||||
resBitmap->ppal = Bitmap->ppal ;
|
||||
GDIOBJ_IncrementShareCount(&Bitmap->ppal->BaseObject);
|
||||
}
|
||||
GDIOBJ_UnlockObjByPtr((POBJ)resBitmap);
|
||||
IntSetBitmapBits(resBitmap, Bitmap->SurfObj.cjBits, Bitmap->SurfObj.pvBits);
|
||||
SURFACE_UnlockSurface(resBitmap);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -967,7 +949,7 @@ BITMAP_CopyBitmap(HBITMAP hBitmap)
|
|||
}
|
||||
}
|
||||
|
||||
GDIOBJ_UnlockObjByPtr((POBJ)Bitmap);
|
||||
SURFACE_UnlockSurface(Bitmap);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -244,129 +244,6 @@ BRUSH_GetObject(PBRUSH pbrush, INT Count, LPLOGBRUSH Buffer)
|
|||
return sizeof(LOGBRUSH);
|
||||
}
|
||||
|
||||
/**
|
||||
* @name CalculateColorTableSize
|
||||
*
|
||||
* Internal routine to calculate the number of color table entries.
|
||||
*
|
||||
* @param BitmapInfoHeader
|
||||
* Input bitmap information header, can be any version of
|
||||
* BITMAPINFOHEADER or BITMAPCOREHEADER.
|
||||
*
|
||||
* @param ColorSpec
|
||||
* Pointer to variable which specifiing the color mode (DIB_RGB_COLORS
|
||||
* or DIB_RGB_COLORS). On successful return this value is normalized
|
||||
* according to the bitmap info.
|
||||
*
|
||||
* @param ColorTableSize
|
||||
* On successful return this variable is filled with number of
|
||||
* entries in color table for the image with specified parameters.
|
||||
*
|
||||
* @return
|
||||
* TRUE if the input values together form a valid image, FALSE otherwise.
|
||||
*/
|
||||
BOOL
|
||||
APIENTRY
|
||||
CalculateColorTableSize(
|
||||
CONST BITMAPINFOHEADER *BitmapInfoHeader,
|
||||
UINT *ColorSpec,
|
||||
UINT *ColorTableSize)
|
||||
{
|
||||
WORD BitCount;
|
||||
DWORD ClrUsed;
|
||||
DWORD Compression;
|
||||
|
||||
/*
|
||||
* At first get some basic parameters from the passed BitmapInfoHeader
|
||||
* structure. It can have one of the following formats:
|
||||
* - BITMAPCOREHEADER (the oldest one with totally different layout
|
||||
* from the others)
|
||||
* - BITMAPINFOHEADER (the standard and most common header)
|
||||
* - BITMAPV4HEADER (extension of BITMAPINFOHEADER)
|
||||
* - BITMAPV5HEADER (extension of BITMAPV4HEADER)
|
||||
*/
|
||||
if (BitmapInfoHeader->biSize == sizeof(BITMAPCOREHEADER))
|
||||
{
|
||||
BitCount = ((LPBITMAPCOREHEADER)BitmapInfoHeader)->bcBitCount;
|
||||
ClrUsed = 0;
|
||||
Compression = BI_RGB;
|
||||
}
|
||||
else
|
||||
{
|
||||
BitCount = BitmapInfoHeader->biBitCount;
|
||||
ClrUsed = BitmapInfoHeader->biClrUsed;
|
||||
Compression = BitmapInfoHeader->biCompression;
|
||||
}
|
||||
|
||||
switch (Compression)
|
||||
{
|
||||
case BI_BITFIELDS:
|
||||
if (*ColorSpec == DIB_PAL_COLORS)
|
||||
*ColorSpec = DIB_RGB_COLORS;
|
||||
|
||||
if (BitCount != 16 && BitCount != 32)
|
||||
return FALSE;
|
||||
|
||||
/* For BITMAPV4HEADER/BITMAPV5HEADER the masks are included in
|
||||
* the structure itself (bV4RedMask, bV4GreenMask, and bV4BlueMask).
|
||||
* For BITMAPINFOHEADER the color masks are stored in the palette. */
|
||||
if (BitmapInfoHeader->biSize > sizeof(BITMAPINFOHEADER))
|
||||
*ColorTableSize = 0;
|
||||
else
|
||||
*ColorTableSize = 3;
|
||||
|
||||
return TRUE;
|
||||
|
||||
case BI_RGB:
|
||||
switch (BitCount)
|
||||
{
|
||||
case 1:
|
||||
*ColorTableSize = ClrUsed ? min(ClrUsed, 2) : 2;
|
||||
return TRUE;
|
||||
|
||||
case 4:
|
||||
*ColorTableSize = ClrUsed ? min(ClrUsed, 16) : 16;
|
||||
return TRUE;
|
||||
|
||||
case 8:
|
||||
*ColorTableSize = ClrUsed ? min(ClrUsed, 256) : 256;
|
||||
return TRUE;
|
||||
|
||||
default:
|
||||
if (*ColorSpec == DIB_PAL_COLORS)
|
||||
*ColorSpec = DIB_RGB_COLORS;
|
||||
if (BitCount != 16 && BitCount != 24 && BitCount != 32)
|
||||
return FALSE;
|
||||
*ColorTableSize = ClrUsed;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
case BI_RLE4:
|
||||
if (BitCount == 4)
|
||||
{
|
||||
*ColorTableSize = ClrUsed ? min(ClrUsed, 16) : 16;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
|
||||
case BI_RLE8:
|
||||
if (BitCount == 8)
|
||||
{
|
||||
*ColorTableSize = ClrUsed ? min(ClrUsed, 256) : 256;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
|
||||
case BI_JPEG:
|
||||
case BI_PNG:
|
||||
*ColorTableSize = ClrUsed;
|
||||
return TRUE;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
HBRUSH
|
||||
APIENTRY
|
||||
IntGdiCreateDIBBrush(
|
||||
|
@ -379,9 +256,7 @@ IntGdiCreateDIBBrush(
|
|||
PBRUSH pbrush;
|
||||
HBITMAP hPattern;
|
||||
ULONG_PTR DataPtr;
|
||||
UINT PaletteEntryCount;
|
||||
PSURFACE psurfPattern;
|
||||
INT PaletteType;
|
||||
HPALETTE hpal ;
|
||||
|
||||
if (BitmapInfo->bmiHeader.biSize < sizeof(BITMAPINFOHEADER))
|
||||
|
@ -390,20 +265,7 @@ IntGdiCreateDIBBrush(
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (!CalculateColorTableSize(&BitmapInfo->bmiHeader,
|
||||
&ColorSpec,
|
||||
&PaletteEntryCount))
|
||||
{
|
||||
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// FIXME: What about BI_BITFIELDS
|
||||
DataPtr = (ULONG_PTR)BitmapInfo + BitmapInfo->bmiHeader.biSize;
|
||||
if (ColorSpec == DIB_RGB_COLORS)
|
||||
DataPtr += PaletteEntryCount * sizeof(RGBQUAD);
|
||||
else
|
||||
DataPtr += PaletteEntryCount * sizeof(USHORT);
|
||||
DataPtr = (ULONG_PTR)BitmapInfo + DIB_BitmapInfoSize(BitmapInfo, ColorSpec);
|
||||
|
||||
hPattern = GreCreateBitmap(BitmapInfo->bmiHeader.biWidth,
|
||||
BitmapInfo->bmiHeader.biHeight,
|
||||
|
@ -418,7 +280,8 @@ IntGdiCreateDIBBrush(
|
|||
|
||||
psurfPattern = SURFACE_LockSurface(hPattern);
|
||||
ASSERT(psurfPattern != NULL);
|
||||
hpal = BuildDIBPalette(BitmapInfo, &PaletteType);
|
||||
if(ColorSpec == DIB_PAL_COLORS) DPRINT1("FIXME, unsupported color spec!\n");
|
||||
hpal = BuildDIBPalette(BitmapInfo);
|
||||
psurfPattern->ppal = PALETTE_ShareLockPalette(hpal);
|
||||
/* Lazy delete palette, it will be freed when its shared reference is zeroed */
|
||||
GreDeleteObject(hpal);
|
||||
|
|
|
@ -262,115 +262,62 @@ IntSetDIBits(
|
|||
UINT StartScan,
|
||||
UINT ScanLines,
|
||||
CONST VOID *Bits,
|
||||
CONST BITMAPV5INFO *bmi,
|
||||
CONST BITMAPINFO *bmi,
|
||||
UINT ColorUse)
|
||||
{
|
||||
SURFACE *bitmap;
|
||||
HBITMAP SourceBitmap;
|
||||
HBITMAP SourceBitmap, hOldSrcBmp = NULL, hOldDstBmp = NULL;
|
||||
HDC hdcSrc, hdcDst;
|
||||
INT result = 0;
|
||||
BOOL copyBitsResult;
|
||||
SURFOBJ *DestSurf, *SourceSurf;
|
||||
SIZEL SourceSize;
|
||||
POINTL ZeroPoint;
|
||||
RECTL DestRect;
|
||||
EXLATEOBJ exlo;
|
||||
PPALETTE ppalDIB;
|
||||
//RGBQUAD *lpRGB;
|
||||
HPALETTE DIB_Palette;
|
||||
ULONG DIB_Palette_Type;
|
||||
INT DIBWidth;
|
||||
PVOID pvBits;
|
||||
|
||||
// Check parameters
|
||||
if (!(bitmap = SURFACE_LockSurface(hBitmap)))
|
||||
SourceBitmap = DIB_CreateDIBSection(DC, bmi, ColorUse, &pvBits, NULL, 0, 0);
|
||||
if (0 == SourceBitmap)
|
||||
{
|
||||
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.bV5Width;
|
||||
SourceSize.cy = ScanLines;
|
||||
|
||||
// Determine width of DIB
|
||||
DIBWidth = DIB_GetDIBWidthBytes(SourceSize.cx, bmi->bmiHeader.bV5BitCount);
|
||||
|
||||
SourceBitmap = EngCreateBitmap(SourceSize,
|
||||
DIBWidth,
|
||||
BitmapFormat(bmi->bmiHeader.bV5BitCount, bmi->bmiHeader.bV5Compression),
|
||||
bmi->bmiHeader.bV5Height < 0 ? BMF_TOPDOWN : 0,
|
||||
(PVOID) Bits);
|
||||
if (0 == SourceBitmap)
|
||||
{
|
||||
SURFACE_UnlockSurface(bitmap);
|
||||
DPRINT1("Error : Could not create a DIBSection.\n");
|
||||
SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
|
||||
return 0;
|
||||
}
|
||||
|
||||
SourceSurf = EngLockSurface((HSURF)SourceBitmap);
|
||||
if (NULL == SourceSurf)
|
||||
{
|
||||
EngDeleteSurface((HSURF)SourceBitmap);
|
||||
SURFACE_UnlockSurface(bitmap);
|
||||
SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
|
||||
return 0;
|
||||
}
|
||||
RtlCopyMemory(pvBits, Bits, DIB_GetDIBImageBytes(bmi->bmiHeader.biWidth,
|
||||
bmi->bmiHeader.biHeight,
|
||||
bmi->bmiHeader.biBitCount));
|
||||
|
||||
ASSERT(bitmap->ppal);
|
||||
hdcSrc = NtGdiCreateCompatibleDC(0);
|
||||
hdcDst = NtGdiCreateCompatibleDC(0);
|
||||
|
||||
// Source palette obtained from the BITMAPINFO
|
||||
DIB_Palette = BuildDIBPalette((BITMAPINFO*)bmi, (PINT)&DIB_Palette_Type);
|
||||
if (NULL == DIB_Palette)
|
||||
{
|
||||
EngUnlockSurface(SourceSurf);
|
||||
EngDeleteSurface((HSURF)SourceBitmap);
|
||||
SURFACE_UnlockSurface(bitmap);
|
||||
SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
|
||||
return 0;
|
||||
}
|
||||
if(!(hdcSrc && hdcDst))
|
||||
{
|
||||
DPRINT1("Error, could not create memory DCs.\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ppalDIB = PALETTE_LockPalette(DIB_Palette);
|
||||
hOldSrcBmp = NtGdiSelectBitmap(hdcSrc, SourceBitmap);
|
||||
hOldDstBmp = NtGdiSelectBitmap(hdcDst, hBitmap);
|
||||
|
||||
/* Initialize XLATEOBJ for color translation */
|
||||
EXLATEOBJ_vInitialize(&exlo, ppalDIB, bitmap->ppal, 0, 0, 0);
|
||||
if(!(hOldSrcBmp && hOldDstBmp))
|
||||
{
|
||||
DPRINT1("Error : Could not select bitmaps into DCs\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Zero point
|
||||
ZeroPoint.x = 0;
|
||||
ZeroPoint.y = 0;
|
||||
result = NtGdiBitBlt(hdcDst, 0, 0, bmi->bmiHeader.biWidth, ScanLines, hdcSrc, 0, StartScan,
|
||||
SRCCOPY, 0, 0);
|
||||
|
||||
// Determine destination rectangle
|
||||
DestRect.left = 0;
|
||||
DestRect.top = abs(bmi->bmiHeader.bV5Height) - StartScan - ScanLines;
|
||||
DestRect.right = SourceSize.cx;
|
||||
DestRect.bottom = DestRect.top + ScanLines;
|
||||
if(result)
|
||||
result = ScanLines;
|
||||
|
||||
copyBitsResult = IntEngCopyBits(DestSurf, SourceSurf, NULL, &exlo.xlo, &DestRect, &ZeroPoint);
|
||||
|
||||
// If it succeeded, return number of scanlines copies
|
||||
if (copyBitsResult == TRUE)
|
||||
{
|
||||
result = SourceSize.cy;
|
||||
// or
|
||||
// result = abs(bmi->bmiHeader.biHeight) - StartScan;
|
||||
}
|
||||
|
||||
// Clean up
|
||||
EXLATEOBJ_vCleanup(&exlo);
|
||||
PALETTE_UnlockPalette(ppalDIB);
|
||||
PALETTE_FreePaletteByHandle(DIB_Palette);
|
||||
EngUnlockSurface(SourceSurf);
|
||||
EngDeleteSurface((HSURF)SourceBitmap);
|
||||
|
||||
// if (ColorUse == DIB_PAL_COLORS)
|
||||
// WinFree((LPSTR)lpRGB);
|
||||
|
||||
SURFACE_UnlockSurface(bitmap);
|
||||
cleanup:
|
||||
if(hdcSrc)
|
||||
{
|
||||
if(hOldSrcBmp) NtGdiSelectBitmap(hdcSrc, hOldSrcBmp);
|
||||
NtGdiDeleteObjectApp(hdcSrc);
|
||||
}
|
||||
if(hdcDst)
|
||||
{
|
||||
if(hOldDstBmp) NtGdiSelectBitmap(hdcDst, hOldDstBmp);
|
||||
NtGdiDeleteObjectApp(hdcDst);
|
||||
}
|
||||
GreDeleteObject(SourceBitmap);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -392,14 +339,19 @@ NtGdiSetDIBits(
|
|||
PDC Dc;
|
||||
INT Ret;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
BITMAPV5INFO bmiLocal;
|
||||
|
||||
if (!Bits) return 0;
|
||||
|
||||
_SEH2_TRY
|
||||
{
|
||||
Status = ProbeAndConvertToBitmapV5Info(&bmiLocal, bmi, ColorUse, 0);
|
||||
ProbeForRead(Bits, bmiLocal.bmiHeader.bV5SizeImage, 1);
|
||||
ProbeForRead(&bmi->bmiHeader.biSize, sizeof(DWORD), 1);
|
||||
ProbeForRead(bmi, bmi->bmiHeader.biSize, 1);
|
||||
ProbeForRead(bmi, DIB_BitmapInfoSize(bmi, ColorUse), 1);
|
||||
ProbeForRead(Bits,
|
||||
DIB_GetDIBImageBytes(bmi->bmiHeader.biWidth,
|
||||
ScanLines,
|
||||
bmi->bmiHeader.biBitCount),
|
||||
1);
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
|
@ -424,7 +376,7 @@ NtGdiSetDIBits(
|
|||
return 0;
|
||||
}
|
||||
|
||||
Ret = IntSetDIBits(Dc, hBitmap, StartScan, ScanLines, Bits, &bmiLocal, ColorUse);
|
||||
Ret = IntSetDIBits(Dc, hBitmap, StartScan, ScanLines, Bits, bmi, ColorUse);
|
||||
|
||||
DC_UnlockDc(Dc);
|
||||
|
||||
|
@ -465,14 +417,12 @@ NtGdiSetDIBitsToDeviceInternal(
|
|||
EXLATEOBJ exlo;
|
||||
PPALETTE ppalDIB = NULL;
|
||||
HPALETTE hpalDIB = NULL;
|
||||
ULONG DIBPaletteType;
|
||||
BITMAPV5INFO bmiLocal ;
|
||||
|
||||
if (!Bits) return 0;
|
||||
|
||||
_SEH2_TRY
|
||||
{
|
||||
Status = ProbeAndConvertToBitmapV5Info(&bmiLocal, bmi, ColorUse, cjMaxInfo);
|
||||
ProbeForRead(bmi, cjMaxInfo, 1);
|
||||
ProbeForRead(Bits, cjMaxBits, 1);
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
|
@ -502,7 +452,7 @@ NtGdiSetDIBitsToDeviceInternal(
|
|||
|
||||
pDestSurf = pSurf ? &pSurf->SurfObj : NULL;
|
||||
|
||||
ScanLines = min(ScanLines, abs(bmiLocal.bmiHeader.bV5Height) - StartScan);
|
||||
ScanLines = min(ScanLines, abs(bmi->bmiHeader.biHeight) - StartScan);
|
||||
|
||||
rcDest.left = XDest;
|
||||
rcDest.top = YDest;
|
||||
|
@ -519,16 +469,16 @@ NtGdiSetDIBitsToDeviceInternal(
|
|||
ptSource.x = XSrc;
|
||||
ptSource.y = YSrc;
|
||||
|
||||
SourceSize.cx = bmiLocal.bmiHeader.bV5Width;
|
||||
SourceSize.cx = bmi->bmiHeader.biWidth;
|
||||
SourceSize.cy = ScanLines;
|
||||
|
||||
DIBWidth = DIB_GetDIBWidthBytes(SourceSize.cx, bmiLocal.bmiHeader.bV5BitCount);
|
||||
DIBWidth = DIB_GetDIBWidthBytes(SourceSize.cx, bmi->bmiHeader.biBitCount);
|
||||
|
||||
hSourceBitmap = EngCreateBitmap(SourceSize,
|
||||
DIBWidth,
|
||||
BitmapFormat(bmiLocal.bmiHeader.bV5BitCount,
|
||||
bmiLocal.bmiHeader.bV5Compression),
|
||||
bmiLocal.bmiHeader.bV5Height < 0 ? BMF_TOPDOWN : 0,
|
||||
BitmapFormat(bmi->bmiHeader.biBitCount,
|
||||
bmi->bmiHeader.biCompression),
|
||||
bmi->bmiHeader.biHeight < 0 ? BMF_TOPDOWN : 0,
|
||||
(PVOID) Bits);
|
||||
if (!hSourceBitmap)
|
||||
{
|
||||
|
@ -547,7 +497,7 @@ NtGdiSetDIBitsToDeviceInternal(
|
|||
ASSERT(pSurf->ppal);
|
||||
|
||||
/* Create a palette for the DIB */
|
||||
hpalDIB = BuildDIBPalette((PBITMAPINFO)&bmiLocal, (PINT)&DIBPaletteType);
|
||||
hpalDIB = BuildDIBPalette(bmi);
|
||||
if (!hpalDIB)
|
||||
{
|
||||
SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
|
||||
|
@ -697,13 +647,6 @@ NtGdiGetDIBitsInternal(
|
|||
ScanLines = 0;
|
||||
goto done;
|
||||
}
|
||||
/* Must not be selected */
|
||||
if(psurf->hdc != NULL)
|
||||
{
|
||||
ScanLines = 0;
|
||||
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Fill in the structure */
|
||||
switch(bpp)
|
||||
|
@ -948,13 +891,14 @@ NtGdiGetDIBitsInternal(
|
|||
}
|
||||
break;
|
||||
}
|
||||
Info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes(width, height, bpp);
|
||||
|
||||
if(Bits && ScanLines)
|
||||
{
|
||||
/* Create a DIBSECTION, blt it, profit */
|
||||
PVOID pDIBits ;
|
||||
HBITMAP hBmpDest, hOldDest = NULL, hOldSrc = NULL;
|
||||
HDC hdcDest, hdcSrc;
|
||||
HDC hdcDest = NULL, hdcSrc;
|
||||
BOOL ret ;
|
||||
|
||||
if (StartScan > psurf->SurfObj.sizlBitmap.cy)
|
||||
|
@ -977,22 +921,38 @@ NtGdiGetDIBitsInternal(
|
|||
goto done ;
|
||||
}
|
||||
|
||||
hdcDest = NtGdiCreateCompatibleDC(0);
|
||||
hdcSrc = NtGdiCreateCompatibleDC(0);
|
||||
|
||||
if(!(hdcSrc && hdcDest))
|
||||
if(psurf->hdc)
|
||||
hdcSrc = psurf->hdc;
|
||||
else
|
||||
{
|
||||
DPRINT1("Error: could not create HDCs!\n");
|
||||
hdcSrc = NtGdiCreateCompatibleDC(0);
|
||||
if(!hdcSrc)
|
||||
{
|
||||
DPRINT1("Error: could not create HDC!\n");
|
||||
ScanLines = 0;
|
||||
goto cleanup_blt;
|
||||
}
|
||||
hOldSrc = NtGdiSelectBitmap(hdcSrc, hBitmap);
|
||||
if(!hOldSrc)
|
||||
{
|
||||
DPRINT1("Error : Could not Select bitmap\n");
|
||||
ScanLines = 0;
|
||||
goto cleanup_blt;
|
||||
}
|
||||
}
|
||||
|
||||
hdcDest = NtGdiCreateCompatibleDC(0);
|
||||
if(!hdcDest)
|
||||
{
|
||||
DPRINT1("Error: could not create HDC!\n");
|
||||
ScanLines = 0;
|
||||
goto cleanup_blt;
|
||||
}
|
||||
|
||||
hOldDest = NtGdiSelectBitmap(hdcDest, hBmpDest);
|
||||
hOldSrc = NtGdiSelectBitmap(hdcSrc, hBitmap);
|
||||
|
||||
if(!(hOldDest && hOldSrc))
|
||||
if(!hOldDest)
|
||||
{
|
||||
DPRINT1("Error : Could not Select bitmaps\n");
|
||||
DPRINT1("Error : Could not Select bitmap\n");
|
||||
ScanLines = 0;
|
||||
goto cleanup_blt;
|
||||
}
|
||||
|
||||
|
@ -1035,7 +995,7 @@ NtGdiGetDIBitsInternal(
|
|||
}
|
||||
|
||||
cleanup_blt:
|
||||
if(hdcSrc)
|
||||
if(hdcSrc && (hdcSrc != psurf->hdc))
|
||||
{
|
||||
if(hOldSrc) NtGdiSelectBitmap(hdcSrc, hOldSrc);
|
||||
NtGdiDeleteObjectApp(hdcSrc);
|
||||
|
@ -1079,11 +1039,10 @@ NtGdiStretchDIBitsInternal(
|
|||
HANDLE hcmXform)
|
||||
{
|
||||
HBITMAP hBitmap, hOldBitmap = NULL;
|
||||
HDC hdcMem;
|
||||
HPALETTE hPal = NULL;
|
||||
PDC pDC;
|
||||
NTSTATUS Status;
|
||||
BITMAPV5INFO bmiLocal ;
|
||||
HDC hdcMem = NULL;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
PVOID pvDIBits;
|
||||
INT Ret = 0;
|
||||
|
||||
if (!Bits || !BitsInfo)
|
||||
{
|
||||
|
@ -1091,101 +1050,82 @@ NtGdiStretchDIBitsInternal(
|
|||
return 0;
|
||||
}
|
||||
|
||||
_SEH2_TRY
|
||||
{
|
||||
Status = ProbeAndConvertToBitmapV5Info(&bmiLocal, BitsInfo, Usage, cjMaxInfo);
|
||||
ProbeForRead(Bits, cjMaxBits, 1);
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
Status = _SEH2_GetExceptionCode();
|
||||
}
|
||||
_SEH2_END
|
||||
/* Create a DIB Section, data will be probed there */
|
||||
hBitmap = NtGdiCreateDIBSection(hDC,
|
||||
NULL,
|
||||
0,
|
||||
BitsInfo,
|
||||
Usage,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
&pvDIBits);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("NtGdiStretchDIBitsInternal fail to read BitMapInfo: %x or Bits: %x\n",BitsInfo,Bits);
|
||||
return 0;
|
||||
}
|
||||
if(!hBitmap)
|
||||
{
|
||||
DPRINT1("Failed to create a DIB.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
hdcMem = NtGdiCreateCompatibleDC(hDC);
|
||||
if (hdcMem == NULL)
|
||||
{
|
||||
DPRINT1("NtGdiCreateCompatibleDC fail create hdc\n");
|
||||
return 0;
|
||||
}
|
||||
_SEH2_TRY
|
||||
{
|
||||
ProbeForRead(Bits, cjMaxBits, 1);
|
||||
RtlCopyMemory(pvDIBits, Bits, DIB_GetDIBImageBytes(BitsInfo->bmiHeader.biWidth,
|
||||
BitsInfo->bmiHeader.biHeight,
|
||||
BitsInfo->bmiHeader.biBitCount));
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
Status = _SEH2_GetExceptionCode();
|
||||
}
|
||||
_SEH2_END
|
||||
|
||||
hBitmap = NtGdiCreateCompatibleBitmap(hDC,
|
||||
abs(bmiLocal.bmiHeader.bV5Width),
|
||||
abs(bmiLocal.bmiHeader.bV5Height));
|
||||
if (hBitmap == NULL)
|
||||
{
|
||||
DPRINT1("NtGdiCreateCompatibleBitmap fail create bitmap\n");
|
||||
DPRINT1("hDC : 0x%08x \n", hDC);
|
||||
DPRINT1("BitsInfo->bmiHeader.biWidth : 0x%08x \n", BitsInfo->bmiHeader.biWidth);
|
||||
DPRINT1("BitsInfo->bmiHeader.biHeight : 0x%08x \n", BitsInfo->bmiHeader.biHeight);
|
||||
return 0;
|
||||
}
|
||||
if(!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Error : Could not read DIB bits\n");
|
||||
SetLastNtError(Status);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Select the bitmap into hdcMem, and save a handle to the old bitmap */
|
||||
hOldBitmap = NtGdiSelectBitmap(hdcMem, hBitmap);
|
||||
hdcMem = NtGdiCreateCompatibleDC(0);
|
||||
if(!hdcMem)
|
||||
{
|
||||
DPRINT1("Failed to create a memory DC!");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (Usage == DIB_PAL_COLORS)
|
||||
{
|
||||
hPal = NtGdiGetDCObject(hDC, GDI_OBJECT_TYPE_PALETTE);
|
||||
hPal = GdiSelectPalette(hdcMem, hPal, FALSE);
|
||||
}
|
||||
hOldBitmap = NtGdiSelectBitmap(hdcMem, hBitmap);
|
||||
if(!hOldBitmap)
|
||||
{
|
||||
DPRINT1("Could not select the DIB into the memory DC\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (bmiLocal.bmiHeader.bV5Compression == BI_RLE4 ||
|
||||
bmiLocal.bmiHeader.bV5Compression == BI_RLE8)
|
||||
{
|
||||
/* copy existing bitmap from destination dc */
|
||||
if (SrcWidth == DestWidth && SrcHeight == DestHeight)
|
||||
NtGdiBitBlt(hdcMem, XSrc, abs(bmiLocal.bmiHeader.bV5Height) - SrcHeight - YSrc,
|
||||
SrcWidth, SrcHeight, hDC, XDest, YDest, ROP, 0, 0);
|
||||
else
|
||||
NtGdiStretchBlt(hdcMem, XSrc, abs(bmiLocal.bmiHeader.bV5Height) - SrcHeight - YSrc,
|
||||
SrcWidth, SrcHeight, hDC, XDest, YDest, DestWidth, DestHeight,
|
||||
ROP, 0);
|
||||
}
|
||||
/* Do we want to stretch ? */
|
||||
if((SrcWidth == DestWidth) && (SrcHeight == DestHeight))
|
||||
{
|
||||
Ret = NtGdiBitBlt(hDC, XDest, YDest, XDest + DestWidth, YDest + DestHeight,
|
||||
hdcMem, XSrc, YSrc, ROP, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
Ret = NtGdiStretchBlt(hDC, XDest, YDest, XDest + DestWidth, YDest + DestHeight,
|
||||
hdcMem, XSrc, YSrc, XSrc + SrcWidth, YSrc + SrcHeight,
|
||||
ROP, 0);
|
||||
}
|
||||
|
||||
pDC = DC_LockDc(hdcMem);
|
||||
if (pDC != NULL)
|
||||
{
|
||||
/* Note BitsInfo->bmiHeader.biHeight is the number of scanline,
|
||||
* if it negitve we getting to many scanline for scanline is UINT not
|
||||
* a INT, so we need make the negtive value to positve and that make the
|
||||
* count correct for negtive bitmap, TODO : we need testcase for this api */
|
||||
IntSetDIBits(pDC, hBitmap, 0, abs(bmiLocal.bmiHeader.bV5Height), Bits,
|
||||
&bmiLocal, Usage);
|
||||
if(Ret)
|
||||
Ret = SrcHeight ;
|
||||
|
||||
DC_UnlockDc(pDC);
|
||||
}
|
||||
cleanup:
|
||||
if(hdcMem)
|
||||
{
|
||||
if(hOldBitmap) NtGdiSelectBitmap(hdcMem, hOldBitmap);
|
||||
NtGdiDeleteObjectApp(hdcMem);
|
||||
}
|
||||
GreDeleteObject(hBitmap);
|
||||
|
||||
|
||||
/* 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(bmiLocal.bmiHeader.bV5Height) - SrcHeight - YSrc,
|
||||
ROP, 0, 0);
|
||||
else
|
||||
NtGdiStretchBlt(hDC, XDest, YDest, DestWidth, DestHeight,
|
||||
hdcMem, XSrc, abs(bmiLocal.bmiHeader.bV5Height) - SrcHeight - YSrc,
|
||||
SrcWidth, SrcHeight, ROP, 0);
|
||||
|
||||
/* cleanup */
|
||||
if (hPal)
|
||||
GdiSelectPalette(hdcMem, hPal, FALSE);
|
||||
|
||||
if (hOldBitmap)
|
||||
NtGdiSelectBitmap(hdcMem, hOldBitmap);
|
||||
|
||||
NtGdiDeleteObjectApp(hdcMem);
|
||||
|
||||
GreDeleteObject(hBitmap);
|
||||
|
||||
return SrcHeight;
|
||||
return Ret;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1198,7 +1138,7 @@ IntCreateDIBitmap(
|
|||
UINT bpp,
|
||||
DWORD init,
|
||||
LPBYTE bits,
|
||||
PBITMAPV5INFO data,
|
||||
PBITMAPINFO data,
|
||||
DWORD coloruse)
|
||||
{
|
||||
HBITMAP handle;
|
||||
|
@ -1211,7 +1151,7 @@ IntCreateDIBitmap(
|
|||
else if ((coloruse != DIB_RGB_COLORS) || (init != CBM_INIT) || !data) fColor = FALSE;
|
||||
else
|
||||
{
|
||||
const RGBQUAD *rgb = data->bmiColors;
|
||||
const RGBQUAD *rgb = (RGBQUAD*)((PBYTE)data + data->bmiHeader.biSize);
|
||||
DWORD col = RGB(rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue);
|
||||
|
||||
// Check if the first color of the colormap is black
|
||||
|
@ -1268,12 +1208,11 @@ NtGdiCreateDIBitmapInternal(
|
|||
IN FLONG fl,
|
||||
IN HANDLE hcmXform)
|
||||
{
|
||||
BITMAPV5INFO bmiLocal ;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
||||
_SEH2_TRY
|
||||
{
|
||||
if(pbmi) Status = ProbeAndConvertToBitmapV5Info(&bmiLocal, pbmi, iUsage, cjMaxInitInfo);
|
||||
if(pbmi) ProbeForRead(pbmi, cjMaxInitInfo, 1);
|
||||
if(pjInit && (fInit == CBM_INIT)) ProbeForRead(pjInit, cjMaxBits, 1);
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
|
@ -1293,7 +1232,7 @@ NtGdiCreateDIBitmapInternal(
|
|||
cy,
|
||||
fInit,
|
||||
pjInit,
|
||||
pbmi ? &bmiLocal : NULL,
|
||||
pbmi,
|
||||
iUsage,
|
||||
fl,
|
||||
hcmXform);
|
||||
|
@ -1307,7 +1246,7 @@ GreCreateDIBitmapInternal(
|
|||
IN INT cy,
|
||||
IN DWORD fInit,
|
||||
IN OPTIONAL LPBYTE pjInit,
|
||||
IN OPTIONAL PBITMAPV5INFO pbmi,
|
||||
IN OPTIONAL PBITMAPINFO pbmi,
|
||||
IN DWORD iUsage,
|
||||
IN FLONG fl,
|
||||
IN HANDLE hcmXform)
|
||||
|
@ -1339,7 +1278,7 @@ GreCreateDIBitmapInternal(
|
|||
/* It's OK to set bpp=0 here, as IntCreateDIBitmap will create a compatible Bitmap
|
||||
* if bpp != 1 and ignore the real value that was passed */
|
||||
if (pbmi)
|
||||
bpp = pbmi->bmiHeader.bV5BitCount;
|
||||
bpp = pbmi->bmiHeader.biBitCount;
|
||||
else
|
||||
bpp = 0;
|
||||
Bmp = IntCreateDIBitmap(Dc, cx, cy, bpp, fInit, pjInit, pbmi, iUsage);
|
||||
|
@ -1435,7 +1374,6 @@ DIB_CreateDIBSection(
|
|||
SURFACE *bmp = NULL;
|
||||
void *mapBits = NULL;
|
||||
HPALETTE hpal ;
|
||||
INT palMode = PAL_INDEXED;
|
||||
|
||||
// Fill BITMAP32 structure with DIB data
|
||||
CONST BITMAPINFOHEADER *bi = &bmi->bmiHeader;
|
||||
|
@ -1527,24 +1465,18 @@ DIB_CreateDIBSection(
|
|||
{
|
||||
PPALETTE pdcPal ;
|
||||
pdcPal = PALETTE_LockPalette(dc->dclevel.hpal);
|
||||
if(!pdcPal)
|
||||
{
|
||||
DPRINT1("Unable to lock DC palette?!\n");
|
||||
goto cleanup;
|
||||
}
|
||||
if(pdcPal->Mode != PAL_INDEXED)
|
||||
{
|
||||
DPRINT1("Not indexed palette selected in the DC?!\n");
|
||||
PALETTE_UnlockPalette(pdcPal);
|
||||
}
|
||||
hpal = PALETTE_AllocPalette(PAL_INDEXED,
|
||||
pdcPal->NumColors,
|
||||
(ULONG*)pdcPal->IndexedColors, 0, 0, 0);
|
||||
hpal = DIB_MapPaletteColors(pdcPal, bmi);
|
||||
PALETTE_UnlockPalette(pdcPal);
|
||||
}
|
||||
else
|
||||
{
|
||||
hpal = BuildDIBPalette(bmi, &palMode);
|
||||
hpal = BuildDIBPalette(bmi);
|
||||
}
|
||||
|
||||
if(!hpal)
|
||||
{
|
||||
DPRINT1("Error : Could not create a aplette for the DIB.\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// Create Device Dependent Bitmap and add DIB pointer
|
||||
|
@ -1716,74 +1648,72 @@ INT FASTCALL DIB_BitmapInfoSize(const BITMAPINFO * info, WORD coloruse)
|
|||
}
|
||||
}
|
||||
|
||||
RGBQUAD *
|
||||
HPALETTE
|
||||
FASTCALL
|
||||
DIB_MapPaletteColors(PDC dc, CONST BITMAPINFO* lpbmi)
|
||||
DIB_MapPaletteColors(PPALETTE ppal, CONST BITMAPINFO* lpbmi)
|
||||
{
|
||||
RGBQUAD *lpRGB;
|
||||
PALETTEENTRY* ppalEntries;
|
||||
ULONG nNumColors,i;
|
||||
USHORT *lpIndex;
|
||||
PPALETTE palGDI;
|
||||
HPALETTE hpal;
|
||||
|
||||
palGDI = PALETTE_LockPalette(dc->dclevel.hpal);
|
||||
|
||||
if (NULL == palGDI)
|
||||
if (ppal->Mode != PAL_INDEXED)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (palGDI->Mode != PAL_INDEXED)
|
||||
{
|
||||
PALETTE_UnlockPalette(palGDI);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nNumColors = 1 << lpbmi->bmiHeader.biBitCount;
|
||||
if (lpbmi->bmiHeader.biClrUsed)
|
||||
{
|
||||
nNumColors = min(nNumColors, lpbmi->bmiHeader.biClrUsed);
|
||||
}
|
||||
|
||||
lpRGB = (RGBQUAD *)ExAllocatePoolWithTag(PagedPool, sizeof(RGBQUAD) * nNumColors, TAG_COLORMAP);
|
||||
if (lpRGB == NULL)
|
||||
/* Don't have more colors than we need */
|
||||
nNumColors = min(ppal->NumColors, nNumColors);
|
||||
|
||||
ppalEntries = ExAllocatePoolWithTag(PagedPool, sizeof(PALETTEENTRY) * nNumColors, TAG_COLORMAP);
|
||||
if (ppalEntries == NULL)
|
||||
{
|
||||
PALETTE_UnlockPalette(palGDI);
|
||||
DPRINT1("Could not allocate palette entries\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lpIndex = (USHORT *)&lpbmi->bmiColors[0];
|
||||
lpIndex = (USHORT *)((PBYTE)lpbmi + lpbmi->bmiHeader.biSize);
|
||||
|
||||
for (i = 0; i < nNumColors; i++)
|
||||
{
|
||||
if (*lpIndex < palGDI->NumColors)
|
||||
if (*lpIndex < ppal->NumColors)
|
||||
{
|
||||
lpRGB[i].rgbRed = palGDI->IndexedColors[*lpIndex].peRed;
|
||||
lpRGB[i].rgbGreen = palGDI->IndexedColors[*lpIndex].peGreen;
|
||||
lpRGB[i].rgbBlue = palGDI->IndexedColors[*lpIndex].peBlue;
|
||||
ppalEntries[i] = ppal->IndexedColors[*lpIndex];
|
||||
}
|
||||
else
|
||||
{
|
||||
lpRGB[i].rgbRed = 0;
|
||||
lpRGB[i].rgbGreen = 0;
|
||||
lpRGB[i].rgbBlue = 0;
|
||||
ppalEntries[i].peRed = 0;
|
||||
ppalEntries[i].peGreen = 0;
|
||||
ppalEntries[i].peBlue = 0;
|
||||
ppalEntries[i].peFlags = 0;
|
||||
}
|
||||
lpRGB[i].rgbReserved = 0;
|
||||
|
||||
lpIndex++;
|
||||
}
|
||||
PALETTE_UnlockPalette(palGDI);
|
||||
|
||||
hpal = PALETTE_AllocPalette(PAL_INDEXED, nNumColors, (ULONG*)ppalEntries, 0, 0, 0);
|
||||
|
||||
return lpRGB;
|
||||
ExFreePoolWithTag(ppalEntries, TAG_COLORMAP);
|
||||
|
||||
return hpal;
|
||||
}
|
||||
|
||||
HPALETTE
|
||||
FASTCALL
|
||||
BuildDIBPalette(CONST BITMAPINFO *bmi, PINT paletteType)
|
||||
BuildDIBPalette(CONST BITMAPINFO *bmi)
|
||||
{
|
||||
BYTE bits;
|
||||
ULONG ColorCount;
|
||||
HPALETTE hPal;
|
||||
ULONG RedMask, GreenMask, BlueMask;
|
||||
ULONG RedMask = 0, GreenMask = 0, BlueMask = 0;
|
||||
PDWORD pdwColors = (PDWORD)((PBYTE)bmi + bmi->bmiHeader.biSize);
|
||||
INT paletteType;
|
||||
|
||||
// Determine Bits Per Pixel
|
||||
bits = bmi->bmiHeader.biBitCount;
|
||||
|
@ -1791,36 +1721,36 @@ BuildDIBPalette(CONST BITMAPINFO *bmi, PINT paletteType)
|
|||
// Determine paletteType from Bits Per Pixel
|
||||
if (bits <= 8)
|
||||
{
|
||||
*paletteType = PAL_INDEXED;
|
||||
paletteType = PAL_INDEXED;
|
||||
RedMask = GreenMask = BlueMask = 0;
|
||||
}
|
||||
else if (bmi->bmiHeader.biCompression == BI_BITFIELDS)
|
||||
{
|
||||
*paletteType = PAL_BITFIELDS;
|
||||
paletteType = PAL_BITFIELDS;
|
||||
RedMask = pdwColors[0];
|
||||
GreenMask = pdwColors[1];
|
||||
BlueMask = pdwColors[2];
|
||||
}
|
||||
else if (bits == 15)
|
||||
{
|
||||
*paletteType = PAL_BITFIELDS;
|
||||
RedMask = 0x7c00;
|
||||
GreenMask = 0x03e0;
|
||||
BlueMask = 0x001f;
|
||||
paletteType = PAL_RGB16_555;
|
||||
}
|
||||
else if (bits == 16)
|
||||
{
|
||||
*paletteType = PAL_BITFIELDS;
|
||||
RedMask = 0xF800;
|
||||
GreenMask = 0x07e0;
|
||||
BlueMask = 0x001f;
|
||||
paletteType = PAL_RGB16_565;
|
||||
}
|
||||
else
|
||||
{
|
||||
*paletteType = PAL_RGB;
|
||||
RedMask = 0xff0000;
|
||||
GreenMask = 0x00ff00;
|
||||
BlueMask = 0x0000ff;
|
||||
if((pdwColors[0] == 0x0000FF) /* R */
|
||||
&& (pdwColors[1] == 0x00FF00) /* G */
|
||||
&& (pdwColors[2] == 0xFF0000))/* B */
|
||||
{
|
||||
paletteType = PAL_BGR;
|
||||
}
|
||||
else
|
||||
{
|
||||
paletteType == PAL_RGB;
|
||||
}
|
||||
}
|
||||
|
||||
if (bmi->bmiHeader.biClrUsed == 0)
|
||||
|
@ -1832,13 +1762,13 @@ BuildDIBPalette(CONST BITMAPINFO *bmi, PINT paletteType)
|
|||
ColorCount = bmi->bmiHeader.biClrUsed;
|
||||
}
|
||||
|
||||
if (PAL_INDEXED == *paletteType)
|
||||
if (PAL_INDEXED == paletteType)
|
||||
{
|
||||
hPal = PALETTE_AllocPaletteIndexedRGB(ColorCount, (RGBQUAD*)pdwColors);
|
||||
}
|
||||
else
|
||||
{
|
||||
hPal = PALETTE_AllocPalette(*paletteType, 0,
|
||||
hPal = PALETTE_AllocPalette(paletteType, 0,
|
||||
NULL,
|
||||
RedMask, GreenMask, BlueMask);
|
||||
}
|
||||
|
@ -1846,195 +1776,6 @@ BuildDIBPalette(CONST BITMAPINFO *bmi, PINT paletteType)
|
|||
return hPal;
|
||||
}
|
||||
|
||||
FORCEINLINE
|
||||
DWORD
|
||||
GetBMIColor(CONST BITMAPINFO* pbmi, INT i)
|
||||
{
|
||||
DWORD dwRet = 0;
|
||||
INT size;
|
||||
if(pbmi->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
|
||||
{
|
||||
/* BITMAPCOREINFO holds RGBTRIPLE values */
|
||||
size = sizeof(RGBTRIPLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
size = sizeof(RGBQUAD);
|
||||
}
|
||||
memcpy(&dwRet, (PBYTE)pbmi + pbmi->bmiHeader.biSize + i*size, size);
|
||||
return dwRet;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
FASTCALL
|
||||
ProbeAndConvertToBitmapV5Info(
|
||||
OUT PBITMAPV5INFO pbmiDst,
|
||||
IN CONST BITMAPINFO* pbmiUnsafe,
|
||||
IN DWORD dwColorUse,
|
||||
IN UINT MaxSize)
|
||||
{
|
||||
DWORD dwSize;
|
||||
ULONG ulWidthBytes;
|
||||
PBITMAPV5HEADER pbmhDst = &pbmiDst->bmiHeader;
|
||||
|
||||
/* Get the size and probe */
|
||||
ProbeForRead(&pbmiUnsafe->bmiHeader.biSize, sizeof(DWORD), 1);
|
||||
dwSize = pbmiUnsafe->bmiHeader.biSize;
|
||||
/* At least dwSize bytes must be valids */
|
||||
ProbeForRead(pbmiUnsafe, max(dwSize, MaxSize), 1);
|
||||
if(!MaxSize)
|
||||
ProbeForRead(pbmiUnsafe, DIB_BitmapInfoSize(pbmiUnsafe, dwColorUse), 1);
|
||||
|
||||
/* Check the size */
|
||||
// FIXME: are intermediate sizes allowed? As what are they interpreted?
|
||||
// make sure we don't use a too big dwSize later
|
||||
if (dwSize != sizeof(BITMAPCOREHEADER) &&
|
||||
dwSize != sizeof(BITMAPINFOHEADER) &&
|
||||
dwSize != sizeof(BITMAPV4HEADER) &&
|
||||
dwSize != sizeof(BITMAPV5HEADER))
|
||||
{
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (dwSize == sizeof(BITMAPCOREHEADER))
|
||||
{
|
||||
PBITMAPCOREHEADER pbch = (PBITMAPCOREHEADER)pbmiUnsafe;
|
||||
|
||||
/* Manually copy the fields that are present */
|
||||
pbmhDst->bV5Width = pbch->bcWidth;
|
||||
pbmhDst->bV5Height = pbch->bcHeight;
|
||||
pbmhDst->bV5Planes = pbch->bcPlanes;
|
||||
pbmhDst->bV5BitCount = pbch->bcBitCount;
|
||||
|
||||
/* Set some default values */
|
||||
pbmhDst->bV5Compression = BI_RGB;
|
||||
pbmhDst->bV5SizeImage = DIB_GetDIBImageBytes(pbch->bcWidth,
|
||||
pbch->bcHeight,
|
||||
pbch->bcPlanes*pbch->bcBitCount) ;
|
||||
pbmhDst->bV5XPelsPerMeter = 72;
|
||||
pbmhDst->bV5YPelsPerMeter = 72;
|
||||
pbmhDst->bV5ClrUsed = 0;
|
||||
pbmhDst->bV5ClrImportant = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Copy valid fields */
|
||||
memcpy(pbmiDst, pbmiUnsafe, dwSize);
|
||||
if(!pbmhDst->bV5SizeImage)
|
||||
pbmhDst->bV5SizeImage = DIB_GetDIBImageBytes(pbmhDst->bV5Width,
|
||||
pbmhDst->bV5Height,
|
||||
pbmhDst->bV5Planes*pbmhDst->bV5BitCount) ;
|
||||
|
||||
if(dwSize < sizeof(BITMAPV5HEADER))
|
||||
{
|
||||
/* Zero out the rest of the V5 header */
|
||||
memset((char*)pbmiDst + dwSize, 0, sizeof(BITMAPV5HEADER) - dwSize);
|
||||
}
|
||||
}
|
||||
pbmhDst->bV5Size = sizeof(BITMAPV5HEADER);
|
||||
|
||||
|
||||
if (dwSize < sizeof(BITMAPV4HEADER))
|
||||
{
|
||||
if (pbmhDst->bV5Compression == BI_BITFIELDS)
|
||||
{
|
||||
pbmhDst->bV5RedMask = GetBMIColor(pbmiUnsafe, 0);
|
||||
pbmhDst->bV5GreenMask = GetBMIColor(pbmiUnsafe, 1);
|
||||
pbmhDst->bV5BlueMask = GetBMIColor(pbmiUnsafe, 2);
|
||||
pbmhDst->bV5AlphaMask = 0;
|
||||
pbmhDst->bV5ClrUsed = 0;
|
||||
}
|
||||
|
||||
// pbmhDst->bV5CSType;
|
||||
// pbmhDst->bV5Endpoints;
|
||||
// pbmhDst->bV5GammaRed;
|
||||
// pbmhDst->bV5GammaGreen;
|
||||
// pbmhDst->bV5GammaBlue;
|
||||
}
|
||||
|
||||
if (dwSize < sizeof(BITMAPV5HEADER))
|
||||
{
|
||||
// pbmhDst->bV5Intent;
|
||||
// pbmhDst->bV5ProfileData;
|
||||
// pbmhDst->bV5ProfileSize;
|
||||
// pbmhDst->bV5Reserved;
|
||||
}
|
||||
|
||||
ulWidthBytes = ((pbmhDst->bV5Width * pbmhDst->bV5Planes *
|
||||
pbmhDst->bV5BitCount + 31) & ~31) / 8;
|
||||
|
||||
if (pbmhDst->bV5SizeImage == 0)
|
||||
pbmhDst->bV5SizeImage = abs(ulWidthBytes * pbmhDst->bV5Height);
|
||||
|
||||
if (pbmhDst->bV5ClrUsed == 0)
|
||||
{
|
||||
switch(pbmhDst->bV5BitCount)
|
||||
{
|
||||
case 1:
|
||||
pbmhDst->bV5ClrUsed = 2;
|
||||
break;
|
||||
case 4:
|
||||
pbmhDst->bV5ClrUsed = 16;
|
||||
break;
|
||||
case 8:
|
||||
pbmhDst->bV5ClrUsed = 256;
|
||||
break;
|
||||
default:
|
||||
pbmhDst->bV5ClrUsed = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (pbmhDst->bV5Planes != 1)
|
||||
{
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (pbmhDst->bV5BitCount != 0 && pbmhDst->bV5BitCount != 1 &&
|
||||
pbmhDst->bV5BitCount != 4 && pbmhDst->bV5BitCount != 8 &&
|
||||
pbmhDst->bV5BitCount != 16 && pbmhDst->bV5BitCount != 24 &&
|
||||
pbmhDst->bV5BitCount != 32)
|
||||
{
|
||||
DPRINT("Invalid bit count: %d\n", pbmhDst->bV5BitCount);
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if ((pbmhDst->bV5BitCount == 0 &&
|
||||
pbmhDst->bV5Compression != BI_JPEG && pbmhDst->bV5Compression != BI_PNG))
|
||||
{
|
||||
DPRINT("Bit count 0 is invalid for compression %d.\n", pbmhDst->bV5Compression);
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (pbmhDst->bV5Compression == BI_BITFIELDS &&
|
||||
pbmhDst->bV5BitCount != 16 && pbmhDst->bV5BitCount != 32)
|
||||
{
|
||||
DPRINT("Bit count %d is invalid for compression BI_BITFIELDS.\n", pbmhDst->bV5BitCount);
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
/* Copy Colors */
|
||||
if(pbmhDst->bV5ClrUsed)
|
||||
{
|
||||
INT i;
|
||||
if(dwColorUse == DIB_PAL_COLORS)
|
||||
{
|
||||
RtlCopyMemory(pbmiDst->bmiColors,
|
||||
pbmiUnsafe->bmiColors,
|
||||
pbmhDst->bV5ClrUsed * sizeof(WORD));
|
||||
}
|
||||
else
|
||||
{
|
||||
for(i = 0; i < pbmhDst->bV5ClrUsed; i++)
|
||||
{
|
||||
((DWORD*)pbmiDst->bmiColors)[i] = GetBMIColor(pbmiUnsafe, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* Converts a BITMAPCOREINFO to a BITMAPINFO structure,
|
||||
* or does nothing if it's already a BITMAPINFO (or V4 or V5) */
|
||||
BITMAPINFO*
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue