Author: jgardou Date: Wed Jun 9 02:08:50 2010 New Revision: 47701
URL: http://svn.reactos.org/svn/reactos?rev=47701&view=rev Log: [WIN32K] - More BITMAPV5INFO fun - Probe max size we are asked for when converting to V5 Info [USER32] [WIN32K] - CreateDIBitmap : Move safety handling to win32k, where it belongs. More code cleanness!
Modified: branches/reactos-yarotows/dll/win32/gdi32/objects/bitmap.c branches/reactos-yarotows/subsystems/win32/win32k/include/bitmaps.h branches/reactos-yarotows/subsystems/win32/win32k/misc/file.c branches/reactos-yarotows/subsystems/win32/win32k/objects/dibobj.c
Modified: branches/reactos-yarotows/dll/win32/gdi32/objects/bitmap.c URL: http://svn.reactos.org/svn/reactos/branches/reactos-yarotows/dll/win32/gdi32... ============================================================================== --- branches/reactos-yarotows/dll/win32/gdi32/objects/bitmap.c [iso-8859-1] (original) +++ branches/reactos-yarotows/dll/win32/gdi32/objects/bitmap.c [iso-8859-1] Wed Jun 9 02:08:50 2010 @@ -43,16 +43,16 @@ if ( Info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER)) { PBITMAPCOREHEADER Core = (PBITMAPCOREHEADER)Info; - Ret = Core->bcHeight * + Ret = Core->bcHeight * ((Core->bcWidth * Core->bcPlanes * Core->bcBitCount + 31) & ~31 ) / 8; } else /* assume BITMAPINFOHEADER */ { - if ((Info->bmiHeader.biCompression) && + if ((Info->bmiHeader.biCompression) && (Info->bmiHeader.biCompression != BI_BITFIELDS)) return Info->bmiHeader.biSizeImage; // Make Height positive always.... - Ret = abs(Info->bmiHeader.biHeight) * + Ret = abs(Info->bmiHeader.biHeight) * ((Info->bmiHeader.biWidth * Info->bmiHeader.biPlanes * Info->bmiHeader.biBitCount + 31) & ~31 ) / 8; } return Ret; @@ -132,12 +132,12 @@ GdiGetBitmapBitsSize(BITMAPINFO *lpbmi) { int retSize; - + if (lpbmi->bmiHeader.biSize == FIELD_OFFSET(BITMAPINFOHEADER, biPlanes)) { /* Calc the bits Size and align it*/ - retSize = HIWORD(lpbmi->bmiHeader.biWidth) * ((LOWORD(lpbmi->bmiHeader.biWidth) * - LOWORD(lpbmi->bmiHeader.biHeight) * HIWORD(lpbmi->bmiHeader.biHeight) + 31) + retSize = HIWORD(lpbmi->bmiHeader.biWidth) * ((LOWORD(lpbmi->bmiHeader.biWidth) * + LOWORD(lpbmi->bmiHeader.biHeight) * HIWORD(lpbmi->bmiHeader.biHeight) + 31) & -32) / 8; } else @@ -148,13 +148,13 @@ if (lpbmi->bmiHeader.biHeight >=0 ) { /* Calc the bits Size and align it*/ - retSize = lpbmi->bmiHeader.biHeight * ((lpbmi->bmiHeader.biWidth * + retSize = lpbmi->bmiHeader.biHeight * ((lpbmi->bmiHeader.biWidth * lpbmi->bmiHeader.biPlanes * lpbmi->bmiHeader.biBitCount + 31) & -32) / 8; } else { /* Make height postiive if it negitve then calc the bits Size and align it*/ - retSize = (-lpbmi->bmiHeader.biHeight) * ((lpbmi->bmiHeader.biWidth * + retSize = (-lpbmi->bmiHeader.biHeight) * ((lpbmi->bmiHeader.biWidth * lpbmi->bmiHeader.biPlanes * lpbmi->bmiHeader.biBitCount + 31) & -32) / 8; } } @@ -189,7 +189,7 @@ { // Verify header due to converted may == info. if ( pConvertedInfo->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER) ) { - if ( pConvertedInfo->bmiHeader.biCompression == BI_JPEG || + if ( pConvertedInfo->bmiHeader.biCompression == BI_JPEG || pConvertedInfo->bmiHeader.biCompression == BI_PNG ) { SetLastError(ERROR_INVALID_PARAMETER); @@ -319,7 +319,7 @@ (!(pbm->bmWidthBytes & 1)) )
{ - + bitmap = CreateBitmap(pbm->bmWidth, pbm->bmHeight, pbm->bmPlanes, @@ -409,7 +409,7 @@ { if ( lpbmi->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER) ) { - if ( lpbmi->bmiHeader.biCompression == BI_JPEG || + if ( lpbmi->bmiHeader.biCompression == BI_JPEG || lpbmi->bmiHeader.biCompression == BI_PNG ) { SetLastError(ERROR_INVALID_PARAMETER); @@ -461,16 +461,11 @@ LONG width, height, compr, dibsize; WORD planes, bpp; // PDC_ATTR pDc_Attr; - PBITMAPINFO pConvertedInfo; UINT ConvertedInfoSize; UINT cjBmpScanSize; - PVOID pvSafeBits = NULL; HBITMAP hBmp;
if (!Header) return 0; - - pConvertedInfo = ConvertBitmapInfo(Data, ColorUse, - &ConvertedInfoSize, FALSE);
if (DIB_GetBitmapInfo(Header, &width, &height, &planes, &bpp, &compr, &dibsize) == -1) { @@ -478,61 +473,28 @@ return NULL; }
- if ( pConvertedInfo ) - { - if ( pConvertedInfo->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER) ) - { - if ( pConvertedInfo->bmiHeader.biCompression == BI_JPEG || - pConvertedInfo->bmiHeader.biCompression == BI_PNG ) - { - hBmp = NULL; - goto Exit; - } - } - } - // For Icm support. // GdiGetHandleUserData(hdc, GDI_OBJECT_TYPE_DC, (PVOID)&pDc_Attr))
- cjBmpScanSize = DIB_BitmapBitsSize((LPBITMAPINFO)pConvertedInfo); - DPRINT("pBMI %x, Size bpp %d, dibsize %d, Conv %d, BSS %d\n", pConvertedInfo,bpp,dibsize,ConvertedInfoSize,cjBmpScanSize); + cjBmpScanSize = DIB_BitmapBitsSize((LPBITMAPINFO)Header); + DPRINT("pBMI %x, Size bpp %d, dibsize %d, Conv %d, BSS %d\n", Data,bpp,dibsize,ConvertedInfoSize,cjBmpScanSize);
if ( !width || !height ) hBmp = GetStockObject(DEFAULT_BITMAP); else { - if ( Bits && Init == CBM_INIT ) - { - pvSafeBits = RtlAllocateHeap(GetProcessHeap(), 0, cjBmpScanSize); - if (pvSafeBits == NULL) - { - hBmp = NULL; - goto Exit; - } - else - { - RtlCopyMemory( pvSafeBits, Bits, cjBmpScanSize); - } - } - hBmp = NtGdiCreateDIBitmapInternal(hDC, width, height, Init, - (LPBYTE)pvSafeBits, - (PBITMAPINFO)pConvertedInfo, + (LPBYTE)Bits, + (LPBITMAPINFO)Data, ColorUse, ConvertedInfoSize, cjBmpScanSize, 0, 0); - - if ( Bits && Init == CBM_INIT ) - RtlFreeHeap(RtlGetProcessHeap(), 0, pvSafeBits); - } -Exit: - if (Data != pConvertedInfo) - RtlFreeHeap(RtlGetProcessHeap(), 0, pConvertedInfo); + } return hBmp; }
@@ -588,7 +550,7 @@
if ( hOldBitmap ) { - if ( hDC ) + if ( hDC ) hPal = SelectPalette(SavehDC, (HPALETTE)GetDCObject(hDC, GDI_OBJECT_TYPE_PALETTE), FALSE);
if ( lpbmi->bmiHeader.biSize < sizeof(BITMAPINFOHEADER)) @@ -782,7 +744,7 @@ /* if ( !pDc_Attr || ((pConvertedInfo->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER)) && - (pConvertedInfo->bmiHeader.biCompression == BI_JPEG || + (pConvertedInfo->bmiHeader.biCompression == BI_JPEG || pConvertedInfo->bmiHeader.biCompression == BI_PNG )) )*/ { LinesCopied = NtGdiSetDIBitsToDeviceInternal( hdc, @@ -806,7 +768,7 @@ RtlFreeHeap(RtlGetProcessHeap(), 0, pvSafeBits); if (lpbmi != pConvertedInfo) RtlFreeHeap(RtlGetProcessHeap(), 0, pConvertedInfo); - + return LinesCopied; }
@@ -933,7 +895,7 @@ /* if ( !pDc_Attr || ((pConvertedInfo->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER)) && - (pConvertedInfo->bmiHeader.biCompression == BI_JPEG || + (pConvertedInfo->bmiHeader.biCompression == BI_JPEG || pConvertedInfo->bmiHeader.biCompression == BI_PNG )) )*/ { LinesCopied = NtGdiStretchDIBitsInternal( hdc,
Modified: branches/reactos-yarotows/subsystems/win32/win32k/include/bitmaps.h URL: http://svn.reactos.org/svn/reactos/branches/reactos-yarotows/subsystems/win3... ============================================================================== --- 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] Wed Jun 9 02:08:50 2010 @@ -13,7 +13,7 @@ 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); +NTSTATUS FASTCALL ProbeAndConvertToBitmapV5Info( OUT PBITMAPV5INFO pbmiDst, IN CONST BITMAPINFO* pbmiUnsafe, IN DWORD dwUse, UINT MaxSize); VOID FASTCALL GetBMIFromBitmapV5Info(IN PBITMAPV5INFO pbmiSrc, OUT PBITMAPINFO pbmiDst, IN DWORD dwUse);
HBITMAP
Modified: branches/reactos-yarotows/subsystems/win32/win32k/misc/file.c URL: http://svn.reactos.org/svn/reactos/branches/reactos-yarotows/subsystems/win3... ============================================================================== --- branches/reactos-yarotows/subsystems/win32/win32k/misc/file.c [iso-8859-1] (original) +++ branches/reactos-yarotows/subsystems/win32/win32k/misc/file.c [iso-8859-1] Wed Jun 9 02:08:50 2010 @@ -199,7 +199,8 @@ { Status = ProbeAndConvertToBitmapV5Info(&bmiLocal, pbmi, - DIB_RGB_COLORS); + DIB_RGB_COLORS, + 0); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
Modified: branches/reactos-yarotows/subsystems/win32/win32k/objects/dibobj.c URL: http://svn.reactos.org/svn/reactos/branches/reactos-yarotows/subsystems/win3... ============================================================================== --- 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] Wed Jun 9 02:08:50 2010 @@ -354,7 +354,8 @@
_SEH2_TRY { - Status = ProbeAndConvertToBitmapV5Info(&bmiLocal, bmi, ColorUse); + Status = ProbeAndConvertToBitmapV5Info(&bmiLocal, bmi, ColorUse, 0); + /* Don't check Bits and hope we won't die */ } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { @@ -427,7 +428,8 @@
_SEH2_TRY { - Status = ProbeAndConvertToBitmapV5Info(&bmiLocal, bmi, ColorUse); + Status = ProbeAndConvertToBitmapV5Info(&bmiLocal, bmi, ColorUse, cjMaxInfo); + ProbeForRead(Bits, cjMaxBits, 1); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { @@ -595,7 +597,7 @@
_SEH2_TRY { - Status = ProbeAndConvertToBitmapV5Info(&bmiLocal, Info, Usage); + Status = ProbeAndConvertToBitmapV5Info(&bmiLocal, Info, Usage, MaxInfo); if (ChkBits) ProbeForWrite(ChkBits, MaxBits, 1); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) @@ -842,7 +844,7 @@ bmiLocal.bmiHeader.bV5BitCount) * DestSize.cy;
hDestBitmap = EngCreateBitmap(DestSize, - DIB_GetDIBWidthBytes(DestSize.cx, + DIB_GetDIBWidthBytes(DestSize.cx, bmiLocal.bmiHeader.bV5BitCount), BitmapFormat(bmiLocal.bmiHeader.bV5BitCount, bmiLocal.bmiHeader.bV5Compression), @@ -942,7 +944,8 @@ HDC hdcMem; HPALETTE hPal = NULL; PDC pDC; - BOOL Hit = FALSE; + NTSTATUS Status; + BITMAPV5INFO bmiLocal ;
if (!Bits || !BitsInfo) { @@ -952,16 +955,16 @@
_SEH2_TRY { - ProbeForRead(BitsInfo, cjMaxInfo, 1); + Status = ProbeAndConvertToBitmapV5Info(&bmiLocal, BitsInfo, Usage, cjMaxInfo); ProbeForRead(Bits, cjMaxBits, 1); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - Hit = TRUE; + Status = _SEH2_GetExceptionCode(); } _SEH2_END
- if (Hit) + if (!NT_SUCCESS(Status)) { DPRINT1("NtGdiStretchDIBitsInternal fail to read BitMapInfo: %x or Bits: %x\n",BitsInfo,Bits); return 0; @@ -975,8 +978,8 @@ }
hBitmap = NtGdiCreateCompatibleBitmap(hDC, - abs(BitsInfo->bmiHeader.biWidth), - abs(BitsInfo->bmiHeader.biHeight)); + abs(bmiLocal.bmiHeader.bV5Width), + abs(bmiLocal.bmiHeader.bV5Height)); if (hBitmap == NULL) { DPRINT1("NtGdiCreateCompatibleBitmap fail create bitmap\n"); @@ -995,15 +998,15 @@ hPal = GdiSelectPalette(hdcMem, hPal, FALSE); }
- if (BitsInfo->bmiHeader.biCompression == BI_RLE4 || - BitsInfo->bmiHeader.biCompression == BI_RLE8) + 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(BitsInfo->bmiHeader.biHeight) - SrcHeight - YSrc, + NtGdiBitBlt(hdcMem, XSrc, abs(bmiLocal.bmiHeader.bV5Height) - SrcHeight - YSrc, SrcWidth, SrcHeight, hDC, XDest, YDest, ROP, 0, 0); else - NtGdiStretchBlt(hdcMem, XSrc, abs(BitsInfo->bmiHeader.biHeight) - SrcHeight - YSrc, + NtGdiStretchBlt(hdcMem, XSrc, abs(bmiLocal.bmiHeader.bV5Height) - SrcHeight - YSrc, SrcWidth, SrcHeight, hDC, XDest, YDest, DestWidth, DestHeight, ROP, 0); } @@ -1015,8 +1018,8 @@ * 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(BitsInfo->bmiHeader.biHeight), Bits, - BitsInfo, Usage); + IntSetDIBits(pDC, hBitmap, 0, abs(bmiLocal.bmiHeader.bV5Height), Bits, + (PBITMAPINFO)&bmiLocal, Usage);
DC_UnlockDc(pDC); } @@ -1026,11 +1029,11 @@ left (negative biHeight) */ if (SrcWidth == DestWidth && SrcHeight == DestHeight) NtGdiBitBlt(hDC, XDest, YDest, DestWidth, DestHeight, - hdcMem, XSrc, abs(BitsInfo->bmiHeader.biHeight) - SrcHeight - YSrc, + hdcMem, XSrc, abs(bmiLocal.bmiHeader.bV5Height) - SrcHeight - YSrc, ROP, 0, 0); else NtGdiStretchBlt(hDC, XDest, YDest, DestWidth, DestHeight, - hdcMem, XSrc, abs(BitsInfo->bmiHeader.biHeight) - SrcHeight - YSrc, + hdcMem, XSrc, abs(bmiLocal.bmiHeader.bV5Height) - SrcHeight - YSrc, SrcWidth, SrcHeight, ROP, 0);
/* cleanup */ @@ -1057,7 +1060,7 @@ UINT bpp, DWORD init, LPBYTE bits, - PBITMAPINFO data, + PBITMAPV5INFO data, DWORD coloruse) { HBITMAP handle; @@ -1070,40 +1073,19 @@ else if ((coloruse != DIB_RGB_COLORS) || (init != CBM_INIT) || !data) fColor = FALSE; else { - if (data->bmiHeader.biSize == sizeof(BITMAPINFOHEADER)) - { - const RGBQUAD *rgb = data->bmiColors; - DWORD col = RGB(rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue); - - // Check if the first color of the colormap is black - if ((col == RGB(0, 0, 0))) - { - rgb++; - col = RGB(rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue); - - // If the second color is white, create a monochrome bitmap - fColor = (col != RGB(0xff,0xff,0xff)); - } - else fColor = TRUE; - } - else if (data->bmiHeader.biSize == sizeof(BITMAPCOREHEADER)) - { - RGBTRIPLE *rgb = ((BITMAPCOREINFO *)data)->bmciColors; - DWORD col = RGB(rgb->rgbtRed, rgb->rgbtGreen, rgb->rgbtBlue); - - if ((col == RGB(0,0,0))) - { - rgb++; - col = RGB(rgb->rgbtRed, rgb->rgbtGreen, rgb->rgbtBlue); - fColor = (col != RGB(0xff,0xff,0xff)); - } - else fColor = TRUE; - } - else - { - DPRINT("(%ld): wrong size for data\n", data->bmiHeader.biSize); - return 0; - } + const RGBQUAD *rgb = data->bmiColors; + DWORD col = RGB(rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue); + + // Check if the first color of the colormap is black + if ((col == RGB(0, 0, 0))) + { + rgb++; + col = RGB(rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue); + + // If the second color is white, create a monochrome bitmap + fColor = (col != RGB(0xff,0xff,0xff)); + } + else fColor = TRUE; }
// Now create the bitmap @@ -1125,7 +1107,7 @@
if (NULL != handle && CBM_INIT == init) { - IntSetDIBits(Dc, handle, 0, height, bits, data, coloruse); + IntSetDIBits(Dc, handle, 0, height, bits, (BITMAPINFO*)data, coloruse); }
return handle; @@ -1151,6 +1133,25 @@ PDC Dc; HBITMAP Bmp; UINT bpp; + BITMAPV5INFO bmiLocal ; + NTSTATUS Status = STATUS_SUCCESS; + + _SEH2_TRY + { + if(pbmi) Status = ProbeAndConvertToBitmapV5Info(&bmiLocal, pbmi, iUsage, cjMaxInitInfo); + if(pjInit && (fInit == CBM_INIT)) ProbeForRead(pjInit, cjMaxBits, 1); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END + + if(!NT_SUCCESS(Status)) + { + SetLastNtError(Status); + return NULL; + }
if (!hDc) // CreateBitmap { // Should use System Bitmap DC hSystemBM, with CreateCompatibleDC for this. @@ -1169,7 +1170,7 @@ return NULL; } bpp = 1; - Bmp = IntCreateDIBitmap(Dc, cx, cy, bpp, fInit, pjInit, pbmi, iUsage); + Bmp = IntCreateDIBitmap(Dc, cx, cy, bpp, fInit, pjInit, pbmi ? &bmiLocal : NULL, iUsage);
DC_UnlockDc(Dc); NtGdiDeleteObjectApp(hDc); @@ -1187,7 +1188,7 @@ should match that of the hdc and not that supplied in bmih. */ if (pbmi) - bpp = pbmi->bmiHeader.biBitCount; + bpp = bmiLocal.bmiHeader.bV5BitCount; else { if (Dc->dctype != DC_TYPE_MEMORY) @@ -1211,7 +1212,7 @@ } } } - Bmp = IntCreateDIBitmap(Dc, cx, cy, bpp, fInit, pjInit, pbmi, iUsage); + Bmp = IntCreateDIBitmap(Dc, cx, cy, bpp, fInit, pjInit, pbmi ? &bmiLocal : NULL, iUsage); DC_UnlockDc(Dc); } return Bmp; @@ -1760,7 +1761,8 @@ ProbeAndConvertToBitmapV5Info( OUT PBITMAPV5INFO pbmiDst, IN CONST BITMAPINFO* pbmiUnsafe, - IN DWORD dwColorUse) + IN DWORD dwColorUse, + IN UINT MaxSize) { DWORD dwSize; ULONG ulWidthBytes; @@ -1769,7 +1771,8 @@ /* Get the size and probe */ ProbeForRead(&pbmiUnsafe->bmiHeader.biSize, sizeof(DWORD), 1); dwSize = pbmiUnsafe->bmiHeader.biSize; - ProbeForRead(pbmiUnsafe, dwSize, 1); + /* At least dwSize bytes must be valids */ + ProbeForRead(pbmiUnsafe, max(dwSize, MaxSize), 1);
/* Check the size */ // FIXME: are intermediate sizes allowed? As what are they interpreted?