diff --git a/win32ss/gdi/gdi32/objects/bitmap.c b/win32ss/gdi/gdi32/objects/bitmap.c index 438521f..c835d77 100644 --- a/win32ss/gdi/gdi32/objects/bitmap.c +++ b/win32ss/gdi/gdi32/objects/bitmap.c @@ -670,6 +670,9 @@ SetDIBitsToDevice( if (!ScanLines || !lpbmi || !Bits) return 0; + if (StartScan > ScanLines) + return 0; + if (ColorUse && ColorUse != DIB_PAL_COLORS && ColorUse != DIB_PAL_COLORS + 1) return 0; @@ -729,7 +732,7 @@ SetDIBitsToDevice( ScanLines = pConvertedInfo->bmiHeader.biHeight; } - cjBmpScanSize = DIB_BitmapMaxBitsSize((LPBITMAPINFO) lpbmi, ScanLines); + cjBmpScanSize = DIB_BitmapMaxBitsSize((LPBITMAPINFO) lpbmi, YSrc + min(ScanLines, abs(Height))); pvSafeBits = RtlAllocateHeap(GetProcessHeap(), 0, cjBmpScanSize); if (pvSafeBits) @@ -742,16 +745,20 @@ SetDIBitsToDevice( { Hit = TRUE; } - _SEH2_END + _SEH2_END; if (Hit) { // We don't die, we continue on with a allocated safe pointer to kernel // space..... - DPRINT1("SetDIBitsToDevice fail to read BitMapInfo: %p or Bits: %p & Size: %u\n", - pConvertedInfo, Bits, cjBmpScanSize); + DPRINT1("SetDIBitsToDevice fail to read BitMapInfo: %p or Bits: %p & Size: %u Height: %u ScanLines: %u\n", + pConvertedInfo, pvSafeBits, cjBmpScanSize, Height, ScanLines); + + LinesCopied = 0; + goto Exit; } - DPRINT("SetDIBitsToDevice Allocate Bits %u!!!\n", cjBmpScanSize); + else + DPRINT("SetDIBitsToDevice Allocate Bits %u\n", cjBmpScanSize); } if (!GdiGetHandleUserData(hdc, GDI_OBJECT_TYPE_DC, (PVOID) & pDc_Attr)) diff --git a/win32ss/gdi/ntgdi/dibobj.c b/win32ss/gdi/ntgdi/dibobj.c index 6c6dd53..5bbbbd7 100644 --- a/win32ss/gdi/ntgdi/dibobj.c +++ b/win32ss/gdi/ntgdi/dibobj.c @@ -496,6 +496,15 @@ NtGdiSetDIBitsToDeviceInternal( if (!Bits) return 0; + ScanLines = min(abs(Height),ScanLines) + YSrc; + + if (ScanLines == 0) + { + DPRINT1("ScanLines == 0\n"); + ret = 0; + goto Exit; + } + pbmiSafe = ExAllocatePoolWithTag(PagedPool, cjMaxInfo, 'pmTG'); if (!pbmiSafe) return 0; @@ -513,14 +522,6 @@ NtGdiSetDIBitsToDeviceInternal( } _SEH2_END; - ScanLines = min(ScanLines, abs(bmi->bmiHeader.biHeight) - StartScan); - if (ScanLines == 0) - { - DPRINT1("ScanLines == 0\n"); - ret = 0; - goto Exit; - } - pDC = DC_LockDc(hDC); if (!pDC) { @@ -561,7 +562,7 @@ NtGdiSetDIBitsToDeviceInternal( //DIBWidth = WIDTH_BYTES_ALIGN32(SourceSize.cx, bmi->bmiHeader.biBitCount); hSourceBitmap = GreCreateBitmapEx(bmi->bmiHeader.biWidth, - ScanLines, + ScanLines + YSrc, 0, BitmapFormat(bmi->bmiHeader.biBitCount, bmi->bmiHeader.biCompression), @@ -638,9 +639,9 @@ NtGdiSetDIBitsToDeviceInternal( pDestSurf = &pSurf->SurfObj; /* Copy the bits */ - DPRINT("BitsToDev with rcDest=(%d|%d) (%d|%d), ptSource=(%d|%d) w=%d h=%d\n", + DPRINT("BitsToDev with rcDest=(%d|%d) (%d|%d), ptSource=(%d|%d) w=%d h=%d ScanLines=%lu Height=%lu Width=%lu pDC->ptlDCOrig.x=%lu pDC->ptlDCOrig.y=%lu bmi->bmiHeader.biCompression=%lu XSrc=%d YSrc=%d Width=%lu Height=%lu StartScan=%lu XDest=%d YDest=%d\n", rcDest.left, rcDest.top, rcDest.right, rcDest.bottom, - ptSource.x, ptSource.y, SourceSize.cx, SourceSize.cy); + ptSource.x, ptSource.y, SourceSize.cx, SourceSize.cy,ScanLines,Height,Width,pDC->ptlDCOrig.x,pDC->ptlDCOrig.y, bmi->bmiHeader.biCompression,XSrc,YSrc,Width,Height,StartScan,XDest,YDest); /* This fixes the large Google text on Google.com from being upside down */ if (rcDest.top > rcDest.bottom) @@ -649,6 +650,20 @@ NtGdiSetDIBitsToDeviceInternal( ptSource.y -= SourceSize.cy; } + + DWORD ROP4 = ROP4_NOOP; + + if(pMaskSurf) + ROP4 = ROP4_MASK; + else + { + //HACK - VERY SPECIFIC FOR CX LOCALIZE + if(rcDest.top == 0 && ptSource.y == 0 && rcDest.bottom == SourceSize.cy && rcDest.left == 0 && ptSource.x == 0 && XSrc == 0 && YSrc == 0 && YDest == 0 && XDest == 0 && StartScan == 0 && rcDest.right == SourceSize.cx && pDC->ptlDCOrig.y == 0 && pDC->ptlDCOrig.x == 0 && Width == Height) + ROP4 = ROP4_FROM_INDEX(R3_OPINDEX_SRCAND); + else + ROP4 = ROP4_FROM_INDEX(R3_OPINDEX_SRCCOPY); + } + bResult = IntEngBitBlt(pDestSurf, pSourceSurf, pMaskSurf, @@ -659,7 +674,7 @@ NtGdiSetDIBitsToDeviceInternal( pMaskSurf ? &ptSource : NULL, NULL, NULL, - pMaskSurf ? ROP4_MASK : ROP4_FROM_INDEX(R3_OPINDEX_SRCCOPY)); + ROP4); /* Cleanup EXLATEOBJ */ EXLATEOBJ_vCleanup(&exlo); @@ -677,7 +692,7 @@ Exit: if (pMaskSurf) EngUnlockSurface(pMaskSurf); if (hMaskBitmap) EngDeleteSurface((HSURF)hMaskBitmap); if (pDC) DC_UnlockDc(pDC); - ExFreePoolWithTag(pbmiSafe, 'pmTG'); + if (pbmiSafe) ExFreePoolWithTag(pbmiSafe, 'pmTG'); return ret; } @@ -1899,9 +1914,9 @@ DIB_CreateDIBSection( //SIZEL Size; HANDLE hSecure; - DPRINT("format (%ld,%ld), planes %u, bpp %u, size %lu, colors %lu (%s)\n", + DPRINT("format (%ld,%ld), planes %u, bpp %u, size %lu, colors %lu (%s) offset (%lu)\n", bi->biWidth, bi->biHeight, bi->biPlanes, bi->biBitCount, - bi->biSizeImage, bi->biClrUsed, usage == DIB_PAL_COLORS? "PAL" : "RGB"); + bi->biSizeImage, bi->biClrUsed, usage == DIB_PAL_COLORS? "PAL" : "RGB",offset); /* CreateDIBSection should fail for compressed formats */ if (bi->biCompression == BI_RLE4 || bi->biCompression == BI_RLE8) @@ -1910,7 +1925,7 @@ DIB_CreateDIBSection( return (HBITMAP)NULL; } - effHeight = bi->biHeight >= 0 ? bi->biHeight : -bi->biHeight; + effHeight = abs(bi->biHeight); bm.bmType = 0; bm.bmWidth = bi->biWidth; bm.bmHeight = effHeight; @@ -1989,7 +2004,7 @@ DIB_CreateDIBSection( //Size.cx = bm.bmWidth; //Size.cy = abs(bm.bmHeight); res = GreCreateBitmapEx(bm.bmWidth, - abs(bm.bmHeight), + bm.bmHeight, bm.bmWidthBytes, BitmapFormat(bi->biBitCount * bi->biPlanes, bi->biCompression), BMF_DONTCACHE | BMF_USERMEM | BMF_NOZEROINIT |