From a09a102a08cac7b2809229b963dfa93f6364d2d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Gardou?= Date: Fri, 24 Oct 2014 17:31:46 +0000 Subject: [PATCH] [WIN32K] - First implementation of CreateDIBitmap with the undocumented CBM_CREATEDIB flag. CORE-8695 svn path=/trunk/; revision=64966 --- reactos/win32ss/gdi/gdi32/objects/bitmap.c | 10 +++ reactos/win32ss/gdi/ntgdi/bitmaps.c | 18 +++--- reactos/win32ss/gdi/ntgdi/dibobj.c | 75 ++++++++++++++++++++-- reactos/win32ss/gdi/ntgdi/intgdi.h | 9 ++- 4 files changed, 95 insertions(+), 17 deletions(-) diff --git a/reactos/win32ss/gdi/gdi32/objects/bitmap.c b/reactos/win32ss/gdi/gdi32/objects/bitmap.c index 3ba54c165ef..4173e4ba84c 100644 --- a/reactos/win32ss/gdi/gdi32/objects/bitmap.c +++ b/reactos/win32ss/gdi/gdi32/objects/bitmap.c @@ -480,6 +480,9 @@ CreateDIBitmap( GdiSetLastError(ERROR_INVALID_PARAMETER); return 0; } + + /* Use the header from the data */ + Header = &Data->bmiHeader; } /* Header is required */ @@ -507,6 +510,13 @@ CreateDIBitmap( return 0; } + /* If some Bits are given, only DIB_PAL_COLORS and DIB_RGB_COLORS are valid */ + if (Bits && (ColorUse > DIB_PAL_COLORS)) + { + GdiSetLastError(ERROR_INVALID_PARAMETER); + return 0; + } + /* Negative width is not allowed */ if (width < 0) return 0; diff --git a/reactos/win32ss/gdi/ntgdi/bitmaps.c b/reactos/win32ss/gdi/ntgdi/bitmaps.c index 430622bf014..e72dec295e7 100644 --- a/reactos/win32ss/gdi/ntgdi/bitmaps.c +++ b/reactos/win32ss/gdi/ntgdi/bitmaps.c @@ -217,7 +217,9 @@ HBITMAP FASTCALL IntCreateCompatibleBitmap( PDC Dc, INT Width, - INT Height) + INT Height, + UINT Planes, + UINT Bpp) { HBITMAP Bmp = NULL; PPALETTE ppal; @@ -234,8 +236,8 @@ IntCreateCompatibleBitmap( Bmp = GreCreateBitmap(abs(Width), abs(Height), - 1, - Dc->ppdev->gdiinfo.cBitsPixel, + Planes ? Planes : 1, + Bpp ? Bpp : Dc->ppdev->gdiinfo.cBitsPixel, NULL); psurf = SURFACE_ShareLockSurface(Bmp); ASSERT(psurf); @@ -266,8 +268,8 @@ IntCreateCompatibleBitmap( Bmp = GreCreateBitmap(abs(Width), abs(Height), - 1, - dibs.dsBm.bmBitsPixel, + Planes ? Planes : 1, + Bpp ? Bpp : dibs.dsBm.bmBitsPixel, NULL); psurfBmp = SURFACE_ShareLockSurface(Bmp); ASSERT(psurfBmp); @@ -291,8 +293,8 @@ IntCreateCompatibleBitmap( bi->bmiHeader.biSize = sizeof(bi->bmiHeader); bi->bmiHeader.biWidth = Width; bi->bmiHeader.biHeight = Height; - bi->bmiHeader.biPlanes = dibs.dsBmih.biPlanes; - bi->bmiHeader.biBitCount = dibs.dsBmih.biBitCount; + bi->bmiHeader.biPlanes = Planes ? Planes : dibs.dsBmih.biPlanes; + bi->bmiHeader.biBitCount = Bpp ? Bpp : dibs.dsBmih.biBitCount; bi->bmiHeader.biCompression = dibs.dsBmih.biCompression; bi->bmiHeader.biSizeImage = 0; bi->bmiHeader.biXPelsPerMeter = dibs.dsBmih.biXPelsPerMeter; @@ -373,7 +375,7 @@ NtGdiCreateCompatibleBitmap( return NULL; } - Bmp = IntCreateCompatibleBitmap(Dc, Width, Height); + Bmp = IntCreateCompatibleBitmap(Dc, Width, Height, 0, 0); DC_UnlockDc(Dc); return Bmp; diff --git a/reactos/win32ss/gdi/ntgdi/dibobj.c b/reactos/win32ss/gdi/ntgdi/dibobj.c index 2dc749ecc1c..304d00e66a4 100644 --- a/reactos/win32ss/gdi/ntgdi/dibobj.c +++ b/reactos/win32ss/gdi/ntgdi/dibobj.c @@ -1317,7 +1317,9 @@ IntCreateDIBitmap( PDC Dc, INT width, INT height, + UINT planes, UINT bpp, + ULONG compression, DWORD init, LPBYTE bits, PBITMAPINFO data, @@ -1325,12 +1327,16 @@ IntCreateDIBitmap( { HBITMAP handle; BOOL fColor; + ULONG BmpFormat = 0; + + if (planes && bpp) + BmpFormat = BitmapFormat(planes * bpp, compression); // 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; + if (BmpFormat != BMF_1BPP) fColor = TRUE; + else if ((coloruse > DIB_RGB_COLORS) || (init != CBM_INIT) || !data) fColor = FALSE; else { const RGBQUAD *rgb = (RGBQUAD*)((PBYTE)data + data->bmiHeader.biSize); @@ -1351,7 +1357,16 @@ IntCreateDIBitmap( // Now create the bitmap if (fColor) { - handle = IntCreateCompatibleBitmap(Dc, width, height); + if (init & CBM_CREATDIB) + { + /* Undocumented flag which creates a DDB of the format specified by the bitmap info. */ + handle = IntCreateCompatibleBitmap(Dc, width, height, planes, bpp); + } + else + { + /* Create a regular compatible bitmap, in the same format as the device */ + handle = IntCreateCompatibleBitmap(Dc, width, height, 0, 0); + } } else { @@ -1365,8 +1380,47 @@ IntCreateDIBitmap( if (height < 0) height = -height; - if (NULL != handle && CBM_INIT == init) + if ((NULL != handle) && (CBM_INIT & init)) { + if (init & CBM_CREATDIB) + { + PSURFACE Surface; + PPALETTE Palette; + NTSTATUS Status = STATUS_SUCCESS; + + Surface = SURFACE_ShareLockSurface(handle); + ASSERT(Surface); + + Palette = CreateDIBPalette(data, Dc, coloruse); + ASSERT(Palette); + SURFACE_vSetPalette(Surface, Palette); + PALETTE_ShareUnlockPalette(Palette); + + if (Surface->SurfObj.pvBits) + { + _SEH2_TRY + { + RtlCopyMemory(Surface->SurfObj.pvBits, bits, + abs(Surface->sizlDim.cy * Surface->SurfObj.lDelta)); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END + } + + SURFACE_ShareUnlockSurface(Surface); + + if (!NT_SUCCESS(Status)) + { + SetLastNtError(Status); + GreDeleteObject(handle); + handle = NULL; + } + return handle; + } + IntSetDIBits(Dc, handle, 0, height, bits, data, coloruse); } @@ -1458,7 +1512,8 @@ GreCreateDIBitmapInternal( { PDC Dc; HBITMAP Bmp; - WORD bpp; + USHORT bpp, planes; + DWORD compression; HDC hdcDest; if (!hDc) /* 1bpp monochrome bitmap */ @@ -1484,10 +1539,18 @@ 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.biBitCount; + planes = pbmi->bmiHeader.biPlanes; + compression = pbmi->bmiHeader.biCompression; + } else + { bpp = 0; - Bmp = IntCreateDIBitmap(Dc, cx, cy, bpp, fInit, pjInit, pbmi, iUsage); + planes = 0; + compression = 0; + } + Bmp = IntCreateDIBitmap(Dc, cx, cy, bpp, planes, compression, fInit, pjInit, pbmi, iUsage); DC_UnlockDc(Dc); if(!hDc) diff --git a/reactos/win32ss/gdi/ntgdi/intgdi.h b/reactos/win32ss/gdi/ntgdi/intgdi.h index 913470a8a02..6971510be01 100644 --- a/reactos/win32ss/gdi/ntgdi/intgdi.h +++ b/reactos/win32ss/gdi/ntgdi/intgdi.h @@ -87,9 +87,12 @@ IntGetSysColor(INT nIndex); HBITMAP FASTCALL -IntCreateCompatibleBitmap(PDC Dc, - INT Width, - INT Height); +IntCreateCompatibleBitmap( + _In_ PDC Dc, + _In_ INT Width, + _In_ INT Height, + _In_ UINT Bpp, + _In_ UINT Planes); WORD APIENTRY IntGdiSetHookFlags(HDC hDC, WORD Flags);