NtGdiCreateDIBitmapInternal: clear CBM_INIT flag, if no bits are given.
IntSetDIBits: Always calculate the bitmap size for uncompressed bitmaps, do not pass uncompressed bits to GreCreateBitmapEx, since they don't have the required alignment (the width in bytes for DIB is 16 bit aligned, bitmaps 32).
Remove a broken ASSERT.

svn path=/trunk/; revision=70482
This commit is contained in:
Timo Kreuzer 2016-01-03 16:16:04 +00:00
parent 4636e8a727
commit de7d65388d
3 changed files with 46 additions and 20 deletions

View file

@ -42,15 +42,15 @@ GreSetBitmapOwner(
return GreSetObjectOwner(hbmp, ulOwner);
}
static
int
BOOL
NTAPI
UnsafeSetBitmapBits(
PSURFACE psurf,
IN ULONG cjBits,
IN PVOID pvBits)
_Inout_ PSURFACE psurf,
_In_ ULONG cjBits,
_In_ const VOID *pvBits)
{
PUCHAR pjDst, pjSrc;
PUCHAR pjDst;
const UCHAR *pjSrc;
LONG lDeltaDst, lDeltaSrc;
ULONG nWidth, nHeight, cBitsPixel;
NT_ASSERT(psurf->flags & API_BITMAP);
@ -69,7 +69,7 @@ UnsafeSetBitmapBits(
/* Make sure the buffer is large enough*/
if (cjBits < (lDeltaSrc * nHeight))
return 0;
return FALSE;
while (nHeight--)
{
@ -79,7 +79,7 @@ UnsafeSetBitmapBits(
pjDst += lDeltaDst;
}
return 1;
return TRUE;
}
HBITMAP

View file

@ -43,3 +43,10 @@ GreCreateDIBitmapInternal(
IN FLONG fl,
IN UINT cjMaxBits,
IN HANDLE hcmXform);
BOOL
NTAPI
UnsafeSetBitmapBits(
_Inout_ PSURFACE psurf,
_In_ ULONG cjBits,
_In_ const VOID *pvBits);

View file

@ -260,23 +260,26 @@ IntSetDIBits(
EXLATEOBJ exlo;
PPALETTE ppalDIB = 0;
ULONG cjSizeImage;
BOOL bCompressed;
if (!bmi) return 0;
if (!bmi || !Bits) return 0;
/* Check if the header provided an image size */
if (bmi->bmiHeader.biSizeImage != 0)
{
/* Use the given size */
cjSizeImage = bmi->bmiHeader.biSizeImage;
}
/* Otherwise check for uncompressed formats */
else if ((bmi->bmiHeader.biCompression == BI_RGB) ||
/* Check for uncompressed formats */
if ((bmi->bmiHeader.biCompression == BI_RGB) ||
(bmi->bmiHeader.biCompression == BI_BITFIELDS))
{
/* Calculate the image size */
cjSizeImage = DIB_GetDIBImageBytes(bmi->bmiHeader.biWidth,
ScanLines,
bmi->bmiHeader.biBitCount);
bCompressed = FALSE;
}
/* Check if the header provided an image size */
else if (bmi->bmiHeader.biSizeImage != 0)
{
/* Use the given size */
cjSizeImage = bmi->bmiHeader.biSizeImage;
bCompressed = TRUE;
}
else
{
@ -293,6 +296,8 @@ IntSetDIBits(
return 0;
}
/* We cannot use the provided buffer for uncompressed bits, since they
might not be aligned correctly! */
SourceBitmap = GreCreateBitmapEx(bmi->bmiHeader.biWidth,
ScanLines,
0,
@ -300,7 +305,7 @@ IntSetDIBits(
bmi->bmiHeader.biCompression),
bmi->bmiHeader.biHeight < 0 ? BMF_TOPDOWN : 0,
cjSizeImage,
(PVOID)Bits,
bCompressed ? (PVOID)Bits : NULL,
0);
if (!SourceBitmap)
{
@ -318,6 +323,17 @@ IntSetDIBits(
goto cleanup;
}
/* Check for uncompressed bits */
if (!bCompressed)
{
/* Copy the bitmap bits */
if (!UnsafeSetBitmapBits(psurfSrc, cjMaxBits, Bits))
{
DPRINT1("Error: Could not set bitmap bits\n");
goto cleanup;
}
}
/* Create a palette for the DIB */
ppalDIB = CreateDIBPalette(bmi, DC, ColorUse);
if (!ppalDIB)
@ -341,8 +357,6 @@ IntSetDIBits(
ptSrc.x = 0;
ptSrc.y = 0;
NT_ASSERT(psurfSrc->SurfObj.cjBits <= cjMaxBits);
result = IntEngCopyBits(&psurfDst->SurfObj,
&psurfSrc->SurfObj,
NULL,
@ -1456,6 +1470,11 @@ NtGdiCreateDIBitmapInternal(
PBYTE safeBits = NULL;
HBITMAP hbmResult = NULL;
if (pjInit == NULL)
{
fInit &= ~CBM_INIT;
}
if(pjInit && (fInit & CBM_INIT))
{
if (cjMaxBits == 0) return NULL;