#define NDEBUG
#include <debug.h>
+// From Yuan, ScanLineSize = (Width * bitcount + 31)/32
+#define WIDTH_BYTES_ALIGN32(cx, bpp) ((((cx) * (bpp) + 31) & ~31) >> 3)
+
/*
* DIB_BitmapInfoSize
*
UINT
FASTCALL
DIB_BitmapMaxBitsSize( PBITMAPINFO Info, UINT ScanLines )
-{
- UINT MaxBits = 0;
-
- if (!Info) return 0;
-
- if (Info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
- {
- PBITMAPCOREHEADER Core = (PBITMAPCOREHEADER)Info;
- MaxBits = Core->bcBitCount * Core->bcPlanes * Core->bcWidth;
- }
- else /* assume BITMAPINFOHEADER */
- {
- if ((Info->bmiHeader.biCompression) && (Info->bmiHeader.biCompression != BI_BITFIELDS))
- return Info->bmiHeader.biSizeImage;
- // Planes are over looked by Yuan. I guess assumed always 1.
- MaxBits = Info->bmiHeader.biBitCount * Info->bmiHeader.biPlanes * Info->bmiHeader.biWidth;
- }
- MaxBits = ((MaxBits + 31) & ~31 ) / 8; // From Yuan, ScanLineSize = (Width * bitcount + 31)/32
- return (MaxBits * ScanLines); // ret the full Size.
-}
-
-UINT
-FASTCALL
-DIB_BitmapBitsSize( CONST BITMAPINFO* Info )
{
UINT Ret;
if ( Info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
{
PBITMAPCOREHEADER Core = (PBITMAPCOREHEADER)Info;
- Ret = Core->bcHeight *
- ((Core->bcWidth * Core->bcPlanes * Core->bcBitCount + 31) & ~31 ) / 8;
+ Ret = WIDTH_BYTES_ALIGN32(Core->bcWidth * Core->bcPlanes, Core->bcBitCount) * ScanLines;
}
else /* assume BITMAPINFOHEADER */
{
- if ((Info->bmiHeader.biCompression) &&
- (Info->bmiHeader.biCompression != BI_BITFIELDS))
- return Info->bmiHeader.biSizeImage;
- // Make Height positive always....
- Ret = abs(Info->bmiHeader.biHeight) *
- ((Info->bmiHeader.biWidth * Info->bmiHeader.biPlanes * Info->bmiHeader.biBitCount + 31) & ~31 ) / 8;
+ if (!(Info->bmiHeader.biCompression) || (Info->bmiHeader.biCompression == BI_BITFIELDS))
+ {
+ Ret = WIDTH_BYTES_ALIGN32(Info->bmiHeader.biWidth * Info->bmiHeader.biPlanes, Info->bmiHeader.biBitCount) * ScanLines;
+ }
+ else
+ {
+ Ret = Info->bmiHeader.biSizeImage;
+ }
}
return Ret;
}
-
/*
* DIB_GetBitmapInfo is complete copy of wine cvs 2/9-2006
* from file dib.c from gdi32.dll or orginal version
WINAPI
GdiGetBitmapBitsSize(BITMAPINFO *lpbmi)
{
- int retSize;
+ UINT Ret;
+
+ if (!lpbmi) return 0;
- if (lpbmi->bmiHeader.biSize == FIELD_OFFSET(BITMAPINFOHEADER, biPlanes))
+ if ( lpbmi->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
{
- /* 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)
- & -32) / 8;
+ PBITMAPCOREHEADER Core = (PBITMAPCOREHEADER)lpbmi;
+ Ret = WIDTH_BYTES_ALIGN32(Core->bcWidth * Core->bcPlanes, Core->bcBitCount) * Core->bcHeight;
}
- else
+ else /* assume BITMAPINFOHEADER */
{
- if ( (lpbmi->bmiHeader.biCompression == BI_BITFIELDS) ||
- (lpbmi->bmiHeader.biCompression == BI_RGB))
+ if (!(lpbmi->bmiHeader.biCompression) || (lpbmi->bmiHeader.biCompression == BI_BITFIELDS))
{
- if (lpbmi->bmiHeader.biHeight >=0 )
- {
- /* Calc the bits Size and align it*/
- 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 *
- lpbmi->bmiHeader.biPlanes * lpbmi->bmiHeader.biBitCount + 31) & -32) / 8;
- }
+ Ret = WIDTH_BYTES_ALIGN32(lpbmi->bmiHeader.biWidth * lpbmi->bmiHeader.biPlanes, lpbmi->bmiHeader.biBitCount) * abs(lpbmi->bmiHeader.biHeight);
}
else
{
- retSize = lpbmi->bmiHeader.biSizeImage;
+ Ret = lpbmi->bmiHeader.biSizeImage;
}
}
- return retSize;
+ return Ret;
}
/*
}
/*
- * @unimplemented
+ * @implemented
*/
HBITMAP WINAPI
CreateBitmap(INT Width,
UINT BitsPixel,
CONST VOID* pUnsafeBits)
{
- /* FIXME some part should be done in user mode */
if (Width && Height)
{
return NtGdiCreateBitmap(Width, Height, Planes, BitsPixel, (LPBYTE) pUnsafeBits);
INT Height)
{
PDC_ATTR pDc_Attr;
- HBITMAP hBmp = NULL;
- DIBSECTION dibs;
if (!GdiGetHandleUserData(hDC, GDI_OBJECT_TYPE_DC, (PVOID)&pDc_Attr))
return NULL;
{
return NtGdiCreateCompatibleBitmap(hDC, Width, Height);
}
+ else
+ {
+ HBITMAP hBmp = NULL;
+ char buffer[sizeof(DIBSECTION) + 256*sizeof(RGBQUAD)];
+ DIBSECTION* pDIBs = (DIBSECTION*)buffer;
- hBmp = NtGdiGetDCObject(hDC, GDI_OBJECT_TYPE_BITMAP);
+ hBmp = NtGdiGetDCObject(hDC, GDI_OBJECT_TYPE_BITMAP);
- if ( GetObjectA(hBmp, sizeof(DIBSECTION), &dibs) != sizeof(DIBSECTION) )
- return NULL;
+ if ( GetObjectA(hBmp, sizeof(DIBSECTION), pDIBs) != sizeof(DIBSECTION) )
+ return NULL;
- if ( dibs.dsBm.bmBitsPixel <= 8 )
- GetDIBColorTable(hDC, 0, 256, (RGBQUAD *)&dibs.dsBitfields);
+ if ( pDIBs->dsBm.bmBitsPixel <= 8 )
+ GetDIBColorTable(hDC, 0, 256, (RGBQUAD *)&pDIBs->dsBitfields[0]);
- dibs.dsBmih.biWidth = Width;
- dibs.dsBmih.biHeight = Height;
+ pDIBs->dsBmih.biWidth = Width;
+ pDIBs->dsBmih.biHeight = Height;
- return CreateDIBSection(hDC, (CONST BITMAPINFO *)&dibs.dsBmih, 0, NULL, NULL, 0);
+ return CreateDIBSection(hDC, (CONST BITMAPINFO *)&pDIBs->dsBmih, 0, NULL, NULL, 0);
+ }
+ return NULL;
}
{
_SEH2_TRY
{
- cjBmpScanSize = DIB_BitmapBitsSize(Data);
+ cjBmpScanSize = GdiGetBitmapBitsSize((BITMAPINFO *)Data);
CalculateColorTableSize(&Data->bmiHeader, &ColorUse, &InfoSize);
InfoSize += Data->bmiHeader.biSize;
}
return hBmp;
}
-#if 0 // FIXME!!! This is a victim of the Win32k Initialization BUG!!!!!
/*
* @implemented
*/
}
}
- hDCc = NtGdiGetDCforBitmap(hBitmap);
+ hDCc = NtGdiGetDCforBitmap(hBitmap); // hDC can be NULL, so, get it from the bitmap.
SavehDC = hDCc;
- if ( !hDCc )
+ if ( !hDCc ) // No DC associated with bitmap, Clone or Create one.
{
nhDC = CreateCompatibleDC(hDC);
if ( !nhDC ) return 0;
return LinesCopied;
}
-#endif
-
-INT
-WINAPI
-SetDIBits(HDC hdc,
- HBITMAP hbmp,
- UINT uStartScan,
- UINT cScanLines,
- CONST VOID *lpvBits,
- CONST BITMAPINFO *lpbmi,
- UINT fuColorUse)
-{
- PBITMAPINFO pConvertedInfo;
- UINT ConvertedInfoSize;
- INT LinesCopied = 0;
- UINT cjBmpScanSize = 0;
- PVOID pvSafeBits = (PVOID)lpvBits;
-
-// This needs to be almost the sames as SetDIBitsToDevice
-
- if ( !cScanLines || !lpbmi || !lpvBits || (GDI_HANDLE_GET_TYPE(hbmp) != GDI_OBJECT_TYPE_BITMAP))
- return 0;
-
- if ( fuColorUse && fuColorUse != DIB_PAL_COLORS && fuColorUse != DIB_PAL_COLORS+1 )
- return 0;
-
- pConvertedInfo = ConvertBitmapInfo(lpbmi, fuColorUse,
- &ConvertedInfoSize, FALSE);
- if (!pConvertedInfo)
- return 0;
-
- cjBmpScanSize = DIB_BitmapMaxBitsSize((LPBITMAPINFO)lpbmi, cScanLines);
-
- if ( lpvBits )
- {
- pvSafeBits = RtlAllocateHeap(GetProcessHeap(), 0, cjBmpScanSize);
- if (pvSafeBits)
- RtlCopyMemory( pvSafeBits, lpvBits, cjBmpScanSize);
- }
-
- LinesCopied = NtGdiSetDIBits( hdc,
- hbmp,
- uStartScan,
- cScanLines,
- pvSafeBits,
- pConvertedInfo,
- fuColorUse);
-
- if ( lpvBits != pvSafeBits)
- RtlFreeHeap(RtlGetProcessHeap(), 0, pvSafeBits);
- if (lpbmi != pConvertedInfo)
- RtlFreeHeap(RtlGetProcessHeap(), 0, pConvertedInfo);
- return LinesCopied;
-}
/*
* @implemented
UINT ConvertedInfoSize;
INT LinesCopied = 0;
UINT cjBmpScanSize = 0;
+ BOOL Hit = FALSE;
PVOID pvSafeBits = (PVOID)Bits;
if ( !ScanLines || !lpbmi || !Bits )
{
pvSafeBits = RtlAllocateHeap(GetProcessHeap(), 0, cjBmpScanSize);
if (pvSafeBits)
- RtlCopyMemory( pvSafeBits, Bits, cjBmpScanSize);
+ {
+ _SEH2_TRY
+ {
+ RtlCopyMemory( pvSafeBits, Bits, cjBmpScanSize);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Hit = TRUE;
+ }
+ _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: %x or Bits: %x & Size: %d\n",pConvertedInfo,Bits,cjBmpScanSize);
+ }
+ DPRINT("SetDIBitsToDevice Allocate Bits %d!!!\n", cjBmpScanSize);
+ }
+
}
if (!GdiGetHandleUserData(hdc, GDI_OBJECT_TYPE_DC, (PVOID)&pDc_Attr))
return 0;
}
/*
- if ( !pDc_Attr ||
+ if ( !pDc_Attr || // DC is Public
+ ColorUse == DIB_PAL_COLORS ||
((pConvertedInfo->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER)) &&
(pConvertedInfo->bmiHeader.biCompression == BI_JPEG ||
pConvertedInfo->bmiHeader.biCompression == BI_PNG )) )*/
return 0;
}
- cjBmpScanSize = DIB_BitmapBitsSize((LPBITMAPINFO)pConvertedInfo);
+ cjBmpScanSize = GdiGetBitmapBitsSize((BITMAPINFO *)pConvertedInfo);
if ( lpBits )
{
}
/*
if ( !pDc_Attr ||
+ iUsage == DIB_PAL_COLORS ||
((pConvertedInfo->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER)) &&
(pConvertedInfo->bmiHeader.biCompression == BI_JPEG ||
pConvertedInfo->bmiHeader.biCompression == BI_PNG )) )*/