if (psurf == NULL)
{
DC_UnlockDc(dc);
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ EngSetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
if (psurf->hSecure == NULL)
{
DC_UnlockDc(dc);
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ EngSetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
if (psurf->ppal == NULL)
{
DC_UnlockDc(dc);
- SetLastWin32Error(ERROR_INVALID_HANDLE);
+ EngSetLastError(ERROR_INVALID_HANDLE);
return 0;
}
if (psurf == NULL)
{
DC_UnlockDc(dc);
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ EngSetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
if (psurf->hSecure == NULL)
{
DC_UnlockDc(dc);
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ EngSetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
if (psurf->ppal == NULL)
{
DC_UnlockDc(dc);
- SetLastWin32Error(ERROR_INVALID_HANDLE);
+ EngSetLastError(ERROR_INVALID_HANDLE);
return 0;
}
if (0 == SourceBitmap)
{
DPRINT1("Error : Could not create a DIBSection.\n");
- SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
+ EngSetLastError(ERROR_NO_SYSTEM_RESOURCES);
return 0;
}
if(!(psurfSrc && psurfDst))
{
- DPRINT1("Error, could not lock surfaces.\n");
+ DPRINT1("Error, could not lock surfaces\n");
goto cleanup;
}
Dc = DC_LockDc(hDC);
if (NULL == Dc)
{
- SetLastWin32Error(ERROR_INVALID_HANDLE);
+ EngSetLastError(ERROR_INVALID_HANDLE);
return 0;
}
if (Dc->dctype == DC_TYPE_INFO)
pDC = DC_LockDc(hDC);
if (!pDC)
{
- SetLastWin32Error(ERROR_INVALID_HANDLE);
+ EngSetLastError(ERROR_INVALID_HANDLE);
return 0;
}
if (pDC->dctype == DC_TYPE_INFO)
SourceSize.cx = bmi->bmiHeader.biWidth;
SourceSize.cy = ScanLines;
- DIBWidth = DIB_GetDIBWidthBytes(SourceSize.cx, bmi->bmiHeader.biBitCount);
+ DIBWidth = WIDTH_BYTES_ALIGN32(SourceSize.cx, bmi->bmiHeader.biBitCount);
hSourceBitmap = EngCreateBitmap(SourceSize,
DIBWidth,
(PVOID) Bits);
if (!hSourceBitmap)
{
- SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
+ EngSetLastError(ERROR_NO_SYSTEM_RESOURCES);
Status = STATUS_NO_MEMORY;
goto Exit;
}
hpalDIB = BuildDIBPalette(bmi);
if (!hpalDIB)
{
- SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
+ EngSetLastError(ERROR_NO_SYSTEM_RESOURCES);
Status = STATUS_NO_MEMORY;
goto Exit;
}
ppalDIB = PALETTE_LockPalette(hpalDIB);
if (!ppalDIB)
{
- SetLastWin32Error(ERROR_INVALID_HANDLE);
+ EngSetLastError(ERROR_INVALID_HANDLE);
Status = STATUS_UNSUCCESSFUL;
goto Exit;
}
if(bitmap_type == -1)
{
DPRINT("Wrong bitmap format\n");
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ EngSetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
else if(bitmap_type == 0)
if(pbmci)
{
pbmci->bmciHeader.bcWidth = psurf->SurfObj.sizlBitmap.cx;
- pbmci->bmciHeader.bcHeight = (psurf->SurfObj.fjBitmap & BMF_TOPDOWN) ?
- -psurf->SurfObj.sizlBitmap.cy :
+ pbmci->bmciHeader.bcHeight = (psurf->SurfObj.fjBitmap & BMF_TOPDOWN) ?
+ -psurf->SurfObj.sizlBitmap.cy :
psurf->SurfObj.sizlBitmap.cy;
pbmci->bmciHeader.bcPlanes = 1;
pbmci->bmciHeader.bcBitCount = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
}
Info->bmiHeader.biWidth = psurf->SurfObj.sizlBitmap.cx;
- Info->bmiHeader.biHeight = (psurf->SurfObj.fjBitmap & BMF_TOPDOWN) ?
- -psurf->SurfObj.sizlBitmap.cy :
+ Info->bmiHeader.biHeight = (psurf->SurfObj.fjBitmap & BMF_TOPDOWN) ?
+ -psurf->SurfObj.sizlBitmap.cy :
psurf->SurfObj.sizlBitmap.cy;;
Info->bmiHeader.biPlanes = 1;
Info->bmiHeader.biBitCount = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
case 8:
Info->bmiHeader.biClrUsed = 0;
- /* If the bitmap if a DIB section and has the same format than what
+ /* If the bitmap if a DIB section and has the same format than what
* we're asked, go ahead! */
- if((psurf->hSecure) &&
+ if((psurf->hSecure) &&
(BitsPerFormat(psurf->SurfObj.iBitmapFormat) == bpp))
{
if(Usage == DIB_RGB_COLORS)
{
unsigned int colors = min(psurf->ppal->NumColors, 1 << bpp);
-
+
if(pbmci)
{
for(i=0; i < colors; i++)
rgbTriples[i].rgbtGreen = pDcPal->IndexedColors[i].peGreen;
rgbTriples[i].rgbtBlue = pDcPal->IndexedColors[i].peBlue;
}
-
+
rgbQuads[i].rgbRed = pDcPal->IndexedColors[i].peRed;
rgbQuads[i].rgbGreen = pDcPal->IndexedColors[i].peGreen;
rgbQuads[i].rgbBlue = pDcPal->IndexedColors[i].peBlue;
{
for(g = 0; g <= 5; g++)
{
- for(b = 0; b <= 5; b++)
+ for(b = 0; b <= 5; b++)
{
colorTriple->rgbtRed = (r * 0xff) / 5;
colorTriple->rgbtGreen = (g * 0xff) / 5;
/* Restore them */
Info->bmiHeader.biWidth = width;
Info->bmiHeader.biHeight = height;
-
+
if(!hBmpDest)
{
DPRINT1("Unable to create a DIB Section!\n");
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ EngSetLastError(ERROR_INVALID_PARAMETER);
ScanLines = 0;
goto done ;
}
Status = STATUS_SUCCESS;
_SEH2_TRY
{
- RtlCopyMemory(Bits, pDIBits, DIB_GetDIBImageBytes (width, height, bpp));
- }
+ RtlCopyMemory(Bits, pDIBits, DIB_GetDIBImageBytes (width, ScanLines, bpp));
+ }
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
Status = _SEH2_GetExceptionCode();
UINT cjMaxBits,
HANDLE hcmXform)
{
- HBITMAP hBitmap, hOldBitmap = NULL;
- HDC hdcMem = NULL;
- NTSTATUS Status = STATUS_SUCCESS;
- PVOID pvDIBits;
- INT Ret = 0;
+ PDC pdc;
+ INT ret = 0;
+ LONG height;
+ LONG width;
+ WORD planes, bpp;
+ DWORD compr, size;
+ HBITMAP hBitmap;
+ HBITMAP hOldBitmap;
+ HDC hdcMem;
+ PVOID pvBits;
+ PBYTE safeBits;
if (!Bits || !BitsInfo)
+ return 0;
+
+ safeBits = ExAllocatePoolWithTag(PagedPool, cjMaxBits, TAG_DIB);
+ if(!safeBits)
{
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
return 0;
}
- /* Create a DIB Section, data will be probed there */
- hBitmap = NtGdiCreateDIBSection(hDC,
- NULL,
- 0,
- BitsInfo,
- Usage,
- 0,
- 0,
- 0,
- &pvDIBits);
+ if (!(pdc = DC_LockDc(hDC)))
+ {
+ ExFreePoolWithTag(safeBits, TAG_DIB);
+ EngSetLastError(ERROR_INVALID_HANDLE);
+ return 0;
+ }
- if(!hBitmap)
- {
- DPRINT1("Failed to create a DIB.\n");
- return 0;
- }
+ _SEH2_TRY
+ {
+ ProbeForRead(BitsInfo, cjMaxInfo, 1);
+ ProbeForRead(Bits, cjMaxBits, 1);
+ if (DIB_GetBitmapInfo(&BitsInfo->bmiHeader, &width, &height, &planes, &bpp, &compr, &size) == -1)
+ {
+ DPRINT1("Invalid bitmap\n");
+ _SEH2_YIELD(goto cleanup;)
+ }
+ RtlCopyMemory(safeBits, Bits, cjMaxBits);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ DPRINT1("Error, failed to read the DIB bits\n");
+ _SEH2_YIELD(goto cleanup;)
+ }
+ _SEH2_END
- /* Set bits */
- _SEH2_TRY
- {
- ProbeForRead(Bits, cjMaxBits, 1);
- RtlCopyMemory(pvDIBits, Bits, DIB_GetDIBImageBytes(BitsInfo->bmiHeader.biWidth,
- BitsInfo->bmiHeader.biHeight,
- BitsInfo->bmiHeader.biBitCount));
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- Status = _SEH2_GetExceptionCode();
- }
- _SEH2_END
+ if (width < 0)
+ {
+ DPRINT1("Bitmap has a negative width\n");
+ return 0;
+ }
- if(!NT_SUCCESS(Status))
- {
- DPRINT1("Error : Could not read DIB bits\n");
- SetLastNtError(Status);
- goto cleanup;
- }
+ hBitmap = NtGdiGetDCObject(hDC, OBJ_BITMAP);
- hdcMem = NtGdiCreateCompatibleDC(0);
- if(!hdcMem)
- {
- DPRINT1("Failed to create a memory DC!");
- goto cleanup;
- }
+ if (XDest == 0 && YDest == 0 && XSrc == 0 && XSrc == 0 &&
+ DestWidth == SrcWidth && DestHeight == SrcHeight &&
+ compr == BI_RGB &&
+ ROP == SRCCOPY)
+ {
+ BITMAP bmp;
+ ret = IntGdiGetObject(hBitmap, sizeof(bmp), &bmp) == sizeof(bmp);
+ if (ret &&
+ bmp.bmBitsPixel == bpp &&
+ bmp.bmWidth == SrcWidth &&
+ bmp.bmHeight == SrcHeight &&
+ bmp.bmPlanes == planes)
+ {
+ /* fast path */
+ ret = IntSetDIBits(pdc, hBitmap, 0, height, safeBits, BitsInfo, Usage);
+ goto cleanup;
+ }
+ }
- hOldBitmap = NtGdiSelectBitmap(hdcMem, hBitmap);
- if(!hOldBitmap)
- {
- DPRINT1("Could not select the DIB into the memory DC\n");
- goto cleanup;
- }
+ /* slow path - need to use StretchBlt */
- /* Do we want to stretch ? */
- if((SrcWidth == DestWidth) && (SrcHeight == DestHeight))
- {
- Ret = NtGdiBitBlt(hDC, XDest, YDest, XDest + DestWidth, YDest + DestHeight,
- hdcMem, XSrc, YSrc, ROP, 0, 0);
- }
- else
- {
- Ret = NtGdiStretchBlt(hDC, XDest, YDest, XDest + DestWidth, YDest + DestHeight,
- hdcMem, XSrc, YSrc, XSrc + SrcWidth, YSrc + SrcHeight,
- ROP, 0);
- }
+ hdcMem = NtGdiCreateCompatibleDC(hDC);
+ hBitmap = DIB_CreateDIBSection(pdc, BitsInfo, Usage, &pvBits, NULL, 0, 0);
+ if(!hBitmap)
+ {
+ DPRINT1("Error, failed to create a DIB section\n");
+ NtGdiDeleteObjectApp(hdcMem);
+ goto cleanup;
+ }
- if(Ret)
- Ret = SrcHeight ;
+ RtlCopyMemory(pvBits, safeBits, cjMaxBits);
+ hOldBitmap = NtGdiSelectBitmap(hdcMem, hBitmap);
-cleanup:
- if(hdcMem)
- {
- if(hOldBitmap) NtGdiSelectBitmap(hdcMem, hOldBitmap);
- NtGdiDeleteObjectApp(hdcMem);
- }
- GreDeleteObject(hBitmap);
+ /* Origin for DIBitmap may be bottom left (positive biHeight) or top
+ left (negative biHeight) */
+ ret = NtGdiStretchBlt(hDC, XDest, YDest, DestWidth, DestHeight,
+ hdcMem, XSrc, abs(height) - SrcHeight - YSrc,
+ SrcWidth, SrcHeight, ROP, 0);
- return Ret;
+ if(ret)
+ ret = SrcHeight;
+ NtGdiSelectBitmap(hdcMem, hOldBitmap);
+ NtGdiDeleteObjectApp(hdcMem);
+ GreDeleteObject(hBitmap);
+
+cleanup:
+ ExFreePoolWithTag(safeBits, TAG_DIB);
+ DC_UnlockDc(pdc);
+ return ret;
}
IN HANDLE hcmXform)
{
NTSTATUS Status = STATUS_SUCCESS;
+ PBYTE safeBits = NULL;
+ HBITMAP hbmResult = NULL;
+
+ if(pjInit && (fInit == CBM_INIT))
+ {
+ safeBits = ExAllocatePoolWithTag(PagedPool, cjMaxBits, TAG_DIB);
+ if(!safeBits)
+ {
+ EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return NULL;
+ }
+ }
_SEH2_TRY
{
if(pbmi) ProbeForRead(pbmi, cjMaxInitInfo, 1);
- if(pjInit && (fInit == CBM_INIT)) ProbeForRead(pjInit, cjMaxBits, 1);
+ if(pjInit && (fInit == CBM_INIT))
+ {
+ ProbeForRead(pjInit, cjMaxBits, 1);
+ RtlCopyMemory(safeBits, pjInit, cjMaxBits);
+ }
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
if(!NT_SUCCESS(Status))
{
SetLastNtError(Status);
- return NULL;
+ goto cleanup;
}
- return GreCreateDIBitmapInternal(hDc,
- cx,
- cy,
- fInit,
- pjInit,
- pbmi,
- iUsage,
- fl,
- hcmXform);
+ hbmResult = GreCreateDIBitmapInternal(hDc,
+ cx,
+ cy,
+ fInit,
+ safeBits,
+ pbmi,
+ iUsage,
+ fl,
+ hcmXform);
+
+cleanup:
+ if (safeBits) ExFreePoolWithTag(safeBits, TAG_DIB);
+ return hbmResult;
}
HBITMAP
Dc = DC_LockDc(hdcDest);
if (!Dc)
{
- SetLastWin32Error(ERROR_INVALID_HANDLE);
+ EngSetLastError(ERROR_INVALID_HANDLE);
return NULL;
}
/* It's OK to set bpp=0 here, as IntCreateDIBitmap will create a compatible Bitmap
}
else
{
- SetLastWin32Error(ERROR_INVALID_HANDLE);
+ EngSetLastError(ERROR_INVALID_HANDLE);
}
if (bDesktopDC)
bm.bmType = 0;
bm.bmWidth = bi->biWidth;
bm.bmHeight = effHeight;
- bm.bmWidthBytes = ovr_pitch ? ovr_pitch : (ULONG) DIB_GetDIBWidthBytes(bm.bmWidth, bi->biBitCount);
+ bm.bmWidthBytes = ovr_pitch ? ovr_pitch : WIDTH_BYTES_ALIGN32(bm.bmWidth, bi->biBitCount);
bm.bmPlanes = bi->biPlanes;
bm.bmBitsPixel = bi->biBitCount;
// Get storage location for DIB bits. Only use biSizeImage if it's valid and
// we're dealing with a compressed bitmap. Otherwise, use width * height.
- totalSize = bi->biSizeImage && bi->biCompression != BI_RGB
+ totalSize = bi->biSizeImage && bi->biCompression != BI_RGB && bi->biCompression != BI_BITFIELDS
? bi->biSizeImage : (ULONG)(bm.bmWidthBytes * effHeight);
if (section)
PAGE_READWRITE);
if (!NT_SUCCESS(Status))
{
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ EngSetLastError(ERROR_INVALID_PARAMETER);
return NULL;
}
hpal = (HPALETTE) 0xFFFFFFFF;
}
}
- else
+ else
{
hpal = BuildDIBPalette(bmi);
}
0);
if (!res)
{
- SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
+ EngSetLastError(ERROR_NO_SYSTEM_RESOURCES);
goto cleanup;
}
bmp = SURFACE_LockSurface(res);
if (NULL == bmp)
{
- SetLastWin32Error(ERROR_INVALID_HANDLE);
+ EngSetLastError(ERROR_INVALID_HANDLE);
goto cleanup;
}
bmp->dwOffset = offset;
bmp->flags = API_BITMAP;
bmp->biClrImportant = bi->biClrImportant;
+ bmp->SurfObj.fjBitmap &= ~BMF_DONT_FREE;
/* HACK */
if(hpal != (HPALETTE)0xFFFFFFFF)
* Get the info from a bitmap header.
* Return 0 for COREHEADER, 1 for INFOHEADER, -1 for error.
*/
-int
+int
FASTCALL
DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, LONG *width,
LONG *height, WORD *planes, WORD *bpp, DWORD *compr, DWORD *size )
*height = core->bcHeight;
*planes = core->bcPlanes;
*bpp = core->bcBitCount;
- *compr = 0;
+ *compr = BI_RGB;
*size = 0;
return 0;
}
return -1;
}
-/***********************************************************************
- * DIB_GetDIBWidthBytes
- *
- * Return the width of a DIB bitmap in bytes. DIB bitmap data is 32-bit aligned.
- * http://www.microsoft.com/msdn/sdk/platforms/doc/sdk/win32/struc/src/str01.htm
- * 11/16/1999 (RJJ) lifted from wine
- */
-INT FASTCALL DIB_GetDIBWidthBytes(INT width, INT depth)
-{
- return ((width * depth + 31) & ~31) >> 3;
-}
-
/***********************************************************************
* DIB_GetDIBImageBytes
*
INT APIENTRY DIB_GetDIBImageBytes(INT width, INT height, INT depth)
{
- return DIB_GetDIBWidthBytes(width, depth) * (height < 0 ? -height : height);
+ return WIDTH_BYTES_ALIGN32(width, depth) * (height < 0 ? -height : height);
}
/***********************************************************************
USHORT *lpIndex;
HPALETTE hpal;
- if (ppal->Mode != PAL_INDEXED)
+ if (!(ppal->flFlags & PAL_INDEXED))
{
return NULL;
}
ppalEntries[i].peBlue = 0;
ppalEntries[i].peFlags = 0;
}
-
+
lpIndex++;
}
-
+
hpal = PALETTE_AllocPalette(PAL_INDEXED, nNumColors, (ULONG*)ppalEntries, 0, 0, 0);
ExFreePoolWithTag(ppalEntries, TAG_COLORMAP);
GreenMask = pdwColors[1];
BlueMask = pdwColors[2];
}
- else if (bits == 15)
- {
- paletteType = PAL_RGB16_555;
- }
- else if (bits == 16)
- {
- paletteType = PAL_RGB16_565;
- }
else
{
- paletteType = PAL_BGR;
+ paletteType = PAL_BITFIELDS;
+ switch (bits)
+ {
+ case 15:
+ paletteType |= PAL_RGB16_555;
+ RedMask = 0x7C00;
+ GreenMask = 0x03E0;
+ BlueMask = 0x001F;
+ break;
+
+ case 16:
+ paletteType |= PAL_RGB16_565;
+ RedMask = 0xF800;
+ GreenMask = 0x07E0;
+ BlueMask = 0x001F;
+ break;
+
+ case 24:
+ case 32:
+ paletteType |= PAL_BGR;
+ RedMask = 0xFF0000;
+ GreenMask = 0x00FF00;
+ BlueMask = 0x0000FF;
+ break;
+ }
}
if (bmi->bmiHeader.biClrUsed == 0)