Author: jgardou
Date: Sun Aug 1 12:17:35 2010
New Revision: 48389
URL:
http://svn.reactos.org/svn/reactos?rev=48389&view=rev
Log:
[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.
Modified:
branches/reactos-yarotows/subsystems/win32/win32k/include/bitmaps.h
branches/reactos-yarotows/subsystems/win32/win32k/include/dib.h
branches/reactos-yarotows/subsystems/win32/win32k/ntuser/clipboard.c
branches/reactos-yarotows/subsystems/win32/win32k/ntuser/cursoricon.c
branches/reactos-yarotows/subsystems/win32/win32k/objects/bitmaps.c
branches/reactos-yarotows/subsystems/win32/win32k/objects/brush.c
branches/reactos-yarotows/subsystems/win32/win32k/objects/dibobj.c
Modified: branches/reactos-yarotows/subsystems/win32/win32k/include/bitmaps.h
URL:
http://svn.reactos.org/svn/reactos/branches/reactos-yarotows/subsystems/win…
==============================================================================
--- branches/reactos-yarotows/subsystems/win32/win32k/include/bitmaps.h [iso-8859-1]
(original)
+++ branches/reactos-yarotows/subsystems/win32/win32k/include/bitmaps.h [iso-8859-1] Sun
Aug 1 12:17:35 2010
@@ -13,7 +13,6 @@
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 @@
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);
Modified: branches/reactos-yarotows/subsystems/win32/win32k/include/dib.h
URL:
http://svn.reactos.org/svn/reactos/branches/reactos-yarotows/subsystems/win…
==============================================================================
--- branches/reactos-yarotows/subsystems/win32/win32k/include/dib.h [iso-8859-1]
(original)
+++ branches/reactos-yarotows/subsystems/win32/win32k/include/dib.h [iso-8859-1] Sun Aug
1 12:17:35 2010
@@ -13,11 +13,11 @@
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);
Modified: branches/reactos-yarotows/subsystems/win32/win32k/ntuser/clipboard.c
URL:
http://svn.reactos.org/svn/reactos/branches/reactos-yarotows/subsystems/win…
==============================================================================
--- branches/reactos-yarotows/subsystems/win32/win32k/ntuser/clipboard.c [iso-8859-1]
(original)
+++ branches/reactos-yarotows/subsystems/win32/win32k/ntuser/clipboard.c [iso-8859-1] Sun
Aug 1 12:17:35 2010
@@ -247,9 +247,11 @@
{
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 @@
/* 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,16 +286,18 @@
}
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;
}
Modified: branches/reactos-yarotows/subsystems/win32/win32k/ntuser/cursoricon.c
URL:
http://svn.reactos.org/svn/reactos/branches/reactos-yarotows/subsystems/win…
==============================================================================
--- branches/reactos-yarotows/subsystems/win32/win32k/ntuser/cursoricon.c [iso-8859-1]
(original)
+++ branches/reactos-yarotows/subsystems/win32/win32k/ntuser/cursoricon.c [iso-8859-1] Sun
Aug 1 12:17:35 2010
@@ -1325,12 +1325,10 @@
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 @@
/* 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 = ((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);
+ Alpha = ptr[3];
+ ptr[0] *= Alpha / 0xff;
+ ptr[1] *= Alpha / 0xff;
+ ptr[2] *= Alpha / 0xff;
+
+ ptr += 4;
}
}
Modified: branches/reactos-yarotows/subsystems/win32/win32k/objects/bitmaps.c
URL:
http://svn.reactos.org/svn/reactos/branches/reactos-yarotows/subsystems/win…
==============================================================================
--- branches/reactos-yarotows/subsystems/win32/win32k/objects/bitmaps.c [iso-8859-1]
(original)
+++ branches/reactos-yarotows/subsystems/win32/win32k/objects/bitmaps.c [iso-8859-1] Sun
Aug 1 12:17:35 2010
@@ -912,7 +912,7 @@
return 0;
}
- Bitmap = GDIOBJ_LockObj(hBitmap, GDI_OBJECT_TYPE_BITMAP);
+ Bitmap = SURFACE_LockSurface(hBitmap);
if (Bitmap == NULL)
{
return 0;
@@ -925,40 +925,22 @@
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 @@
}
}
- GDIOBJ_UnlockObjByPtr((POBJ)Bitmap);
+ SURFACE_UnlockSurface(Bitmap);
return res;
}
Modified: branches/reactos-yarotows/subsystems/win32/win32k/objects/brush.c
URL:
http://svn.reactos.org/svn/reactos/branches/reactos-yarotows/subsystems/win…
==============================================================================
--- branches/reactos-yarotows/subsystems/win32/win32k/objects/brush.c [iso-8859-1]
(original)
+++ branches/reactos-yarotows/subsystems/win32/win32k/objects/brush.c [iso-8859-1] Sun Aug
1 12:17:35 2010
@@ -244,129 +244,6 @@
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 @@
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 @@
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 @@
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);
Modified: branches/reactos-yarotows/subsystems/win32/win32k/objects/dibobj.c
URL:
http://svn.reactos.org/svn/reactos/branches/reactos-yarotows/subsystems/win…
==============================================================================
--- branches/reactos-yarotows/subsystems/win32/win32k/objects/dibobj.c [iso-8859-1]
(original)
+++ branches/reactos-yarotows/subsystems/win32/win32k/objects/dibobj.c [iso-8859-1] Sun
Aug 1 12:17:35 2010
@@ -262,115 +262,62 @@
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;
-
- // Check parameters
- if (!(bitmap = SURFACE_LockSurface(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.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);
+ PVOID pvBits;
+
+ SourceBitmap = DIB_CreateDIBSection(DC, bmi, ColorUse, &pvBits, NULL, 0, 0);
+ if (0 == SourceBitmap)
+ {
+ 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;
- }
-
- ASSERT(bitmap->ppal);
-
- // 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;
- }
-
- ppalDIB = PALETTE_LockPalette(DIB_Palette);
-
- /* Initialize XLATEOBJ for color translation */
- EXLATEOBJ_vInitialize(&exlo, ppalDIB, bitmap->ppal, 0, 0, 0);
-
- // Zero point
- ZeroPoint.x = 0;
- ZeroPoint.y = 0;
-
- // Determine destination rectangle
- DestRect.left = 0;
- DestRect.top = abs(bmi->bmiHeader.bV5Height) - StartScan - ScanLines;
- DestRect.right = SourceSize.cx;
- DestRect.bottom = DestRect.top + 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);
+ RtlCopyMemory(pvBits, Bits, DIB_GetDIBImageBytes(bmi->bmiHeader.biWidth,
+ bmi->bmiHeader.biHeight,
+ bmi->bmiHeader.biBitCount));
+
+ hdcSrc = NtGdiCreateCompatibleDC(0);
+ hdcDst = NtGdiCreateCompatibleDC(0);
+
+ if(!(hdcSrc && hdcDst))
+ {
+ DPRINT1("Error, could not create memory DCs.\n");
+ goto cleanup;
+ }
+
+ hOldSrcBmp = NtGdiSelectBitmap(hdcSrc, SourceBitmap);
+ hOldDstBmp = NtGdiSelectBitmap(hdcDst, hBitmap);
+
+ if(!(hOldSrcBmp && hOldDstBmp))
+ {
+ DPRINT1("Error : Could not select bitmaps into DCs\n");
+ goto cleanup;
+ }
+
+ result = NtGdiBitBlt(hdcDst, 0, 0, bmi->bmiHeader.biWidth, ScanLines, hdcSrc, 0,
StartScan,
+ SRCCOPY, 0, 0);
+
+ if(result)
+ result = ScanLines;
+
+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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
}
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 @@
goto done ;
}
+ if(psurf->hdc)
+ hdcSrc = psurf->hdc;
+ else
+ {
+ 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);
- hdcSrc = NtGdiCreateCompatibleDC(0);
-
- if(!(hdcSrc && hdcDest))
+ if(!hdcDest)
{
- DPRINT1("Error: could not create HDCs!\n");
+ 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 @@
}
cleanup_blt:
- if(hdcSrc)
+ if(hdcSrc && (hdcSrc != psurf->hdc))
{
if(hOldSrc) NtGdiSelectBitmap(hdcSrc, hOldSrc);
NtGdiDeleteObjectApp(hdcSrc);
@@ -1079,11 +1039,10 @@
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 @@
return 0;
}
- _SEH2_TRY
- {
- Status = ProbeAndConvertToBitmapV5Info(&bmiLocal, BitsInfo, Usage,
cjMaxInfo);
- ProbeForRead(Bits, cjMaxBits, 1);
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- Status = _SEH2_GetExceptionCode();
- }
- _SEH2_END
-
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("NtGdiStretchDIBitsInternal fail to read BitMapInfo: %x or Bits:
%x\n",BitsInfo,Bits);
- return 0;
- }
-
- hdcMem = NtGdiCreateCompatibleDC(hDC);
- if (hdcMem == NULL)
- {
- DPRINT1("NtGdiCreateCompatibleDC fail create hdc\n");
- return 0;
- }
-
- 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;
- }
-
- /* Select the bitmap into hdcMem, and save a handle to the old bitmap */
- hOldBitmap = NtGdiSelectBitmap(hdcMem, hBitmap);
-
- if (Usage == DIB_PAL_COLORS)
- {
- hPal = NtGdiGetDCObject(hDC, GDI_OBJECT_TYPE_PALETTE);
- hPal = GdiSelectPalette(hdcMem, hPal, FALSE);
- }
-
- 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);
- }
-
- 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);
-
- DC_UnlockDc(pDC);
- }
-
-
- /* 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;
+ /* Create a DIB Section, data will be probed there */
+ hBitmap = NtGdiCreateDIBSection(hDC,
+ NULL,
+ 0,
+ BitsInfo,
+ Usage,
+ 0,
+ 0,
+ 0,
+ &pvDIBits);
+
+ if(!hBitmap)
+ {
+ DPRINT1("Failed to create a DIB.\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
+
+ if(!NT_SUCCESS(Status))
+ {
+ DPRINT1("Error : Could not read DIB bits\n");
+ SetLastNtError(Status);
+ goto cleanup;
+ }
+
+ hdcMem = NtGdiCreateCompatibleDC(0);
+ if(!hdcMem)
+ {
+ DPRINT1("Failed to create a memory DC!");
+ goto cleanup;
+ }
+
+ hOldBitmap = NtGdiSelectBitmap(hdcMem, hBitmap);
+ if(!hOldBitmap)
+ {
+ DPRINT1("Could not select the DIB into the memory DC\n");
+ goto cleanup;
+ }
+
+ /* 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);
+ }
+
+ if(Ret)
+ Ret = SrcHeight ;
+
+cleanup:
+ if(hdcMem)
+ {
+ if(hOldBitmap) NtGdiSelectBitmap(hdcMem, hOldBitmap);
+ NtGdiDeleteObjectApp(hdcMem);
+ }
+ GreDeleteObject(hBitmap);
+
+ return Ret;
}
@@ -1198,7 +1138,7 @@
UINT bpp,
DWORD init,
LPBYTE bits,
- PBITMAPV5INFO data,
+ PBITMAPINFO data,
DWORD coloruse)
{
HBITMAP handle;
@@ -1211,7 +1151,7 @@
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 @@
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 @@
cy,
fInit,
pjInit,
- pbmi ? &bmiLocal : NULL,
+ pbmi,
iUsage,
fl,
hcmXform);
@@ -1307,7 +1246,7 @@
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 @@
/* 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 @@
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 @@
{
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,25 +1648,17 @@
}
}
-RGBQUAD *
+HPALETTE
FASTCALL
-DIB_MapPaletteColors(PDC dc, CONST BITMAPINFO* lpbmi)
-{
- RGBQUAD *lpRGB;
+DIB_MapPaletteColors(PPALETTE ppal, CONST BITMAPINFO* lpbmi)
+{
+ PALETTEENTRY* ppalEntries;
ULONG nNumColors,i;
USHORT *lpIndex;
- PPALETTE palGDI;
-
- palGDI = PALETTE_LockPalette(dc->dclevel.hpal);
-
- if (NULL == palGDI)
- {
- return NULL;
- }
-
- if (palGDI->Mode != PAL_INDEXED)
- {
- PALETTE_UnlockPalette(palGDI);
+ HPALETTE hpal;
+
+ if (ppal->Mode != PAL_INDEXED)
+ {
return NULL;
}
@@ -1744,46 +1668,52 @@
nNumColors = min(nNumColors, lpbmi->bmiHeader.biClrUsed);
}
- lpRGB = (RGBQUAD *)ExAllocatePoolWithTag(PagedPool, sizeof(RGBQUAD) * nNumColors,
TAG_COLORMAP);
- if (lpRGB == NULL)
- {
- PALETTE_UnlockPalette(palGDI);
+ /* Don't have more colors than we need */
+ nNumColors = min(ppal->NumColors, nNumColors);
+
+ ppalEntries = ExAllocatePoolWithTag(PagedPool, sizeof(PALETTEENTRY) * nNumColors,
TAG_COLORMAP);
+ if (ppalEntries == NULL)
+ {
+ 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);
-
- return lpRGB;
+
+ hpal = PALETTE_AllocPalette(PAL_INDEXED, nNumColors, (ULONG*)ppalEntries, 0, 0, 0);
+
+ 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 @@
// 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,207 +1762,18 @@
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);
}
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,