Author: tkreuzer Date: Thu Oct 6 10:56:58 2011 New Revision: 54019
URL: http://svn.reactos.org/svn/reactos?rev=54019&view=rev Log: [WIN32K] Fix handling of RLE compressed bitmaps in NtGdiStretchDIBitsInternal, by using similar code as in NtGdiSetDIBitsToDeviceInternal calling GreCreateBitmapEx instead of NtGdiCreateDIBitmapInternal. Fixes bug 6168.
Modified: trunk/reactos/subsystems/win32/win32k/objects/dibobj.c
Modified: trunk/reactos/subsystems/win32/win32k/objects/dibobj.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/obj... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/objects/dibobj.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/objects/dibobj.c [iso-8859-1] Thu Oct 6 10:56:58 2011 @@ -979,9 +979,12 @@ SIZEL sizel; RECTL rcSrc, rcDst; PDC pdc; - HBITMAP hbmTmp; - PSURFACE psurfTmp, psurfDst; + HBITMAP hbmTmp = 0; + PSURFACE psurfTmp = 0, psurfDst = 0; + HPALETTE hpalDIB = 0; + PPALETTE ppalDIB = 0; EXLATEOBJ exlo; + PVOID pvBits;
if (!(pdc = DC_LockDc(hdc))) { @@ -1017,37 +1020,28 @@ hcmXform); }
- /* Create an intermediate bitmap from the DIB */ - hbmTmp = NtGdiCreateDIBitmapInternal(hdc, - cxSrc, - cySrc, - CBM_INIT, - pjInit, - pbmi, - dwUsage, - cjMaxInfo, - cjMaxBits, - 0, - hcmXform); - if (!hbmTmp) - { - DPRINT1("NtGdiCreateDIBitmapInternal failed\n"); + pvBits = ExAllocatePoolWithTag(PagedPool, cjMaxBits, 'pmeT'); + if (!pvBits) + { return 0; } + + _SEH2_TRY + { + ProbeForRead(pjInit, cjMaxBits, 1); + RtlCopyMemory(pvBits, pjInit, cjMaxBits); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + _SEH2_YIELD(return 0); + } + _SEH2_END
/* FIXME: locking twice is cheesy, coord tranlation in UM will fix it */ if (!(pdc = DC_LockDc(hdc))) { DPRINT1("Could not lock dc\n"); EngSetLastError(ERROR_INVALID_HANDLE); - GreDeleteObject(hbmTmp); - return 0; - } - - psurfTmp = SURFACE_ShareLockSurface(hbmTmp); - if (!psurfTmp) - { - DPRINT1("Could not lock bitmap :-(\n"); goto cleanup; }
@@ -1071,9 +1065,48 @@ IntLPtoDP(pdc, (POINTL*)&rcDst, 2); RECTL_vOffsetRect(&rcDst, pdc->ptlDCOrig.x, pdc->ptlDCOrig.y);
+ hbmTmp = GreCreateBitmapEx(pbmi->bmiHeader.biWidth, + pbmi->bmiHeader.biHeight, + 0, + BitmapFormat(pbmi->bmiHeader.biBitCount, + pbmi->bmiHeader.biCompression), + pbmi->bmiHeader.biHeight < 0 ? BMF_TOPDOWN : 0, + pbmi->bmiHeader.biSizeImage, + pvBits, + 0); + + if (!hbmTmp) + { + bResult = FALSE; + goto cleanup; + } + + psurfTmp = SURFACE_ShareLockSurface(hbmTmp); + if (!psurfTmp) + { + bResult = FALSE; + goto cleanup; + } + + /* Create a palette for the DIB */ + hpalDIB = BuildDIBPalette(pbmi); + if (!hpalDIB) + { + bResult = FALSE; + goto cleanup; + } + + /* Lock the DIB palette */ + ppalDIB = PALETTE_ShareLockPalette(hpalDIB); + if (!ppalDIB) + { + bResult = FALSE; + goto cleanup; + } + /* Initialize XLATEOBJ */ EXLATEOBJ_vInitialize(&exlo, - psurfTmp->ppal, + ppalDIB, psurfDst->ppal, RGB(0xff, 0xff, 0xff), pdc->pdcattr->crBackgroundClr, @@ -1099,9 +1132,12 @@ DC_vFinishBlit(pdc, NULL); EXLATEOBJ_vCleanup(&exlo); cleanup: + if (ppalDIB) PALETTE_ShareUnlockPalette(ppalDIB); + if (hpalDIB) GreDeleteObject(hpalDIB); if (psurfTmp) SURFACE_ShareUnlockSurface(psurfTmp); if (hbmTmp) GreDeleteObject(hbmTmp); if (pdc) DC_UnlockDc(pdc); + ExFreePoolWithTag(pvBits, 'pmeT');
return bResult; } @@ -1390,6 +1426,7 @@ if (bi->biCompression == BI_RLE4 || bi->biCompression == BI_RLE8) { DPRINT1("no compressed format allowed\n"); + __debugbreak(); return (HBITMAP)NULL; }