2005-07-31 12:11:56 +00:00
|
|
|
#include "precomp.h"
|
|
|
|
|
2008-03-30 22:37:42 +00:00
|
|
|
#define NDEBUG
|
|
|
|
#include <debug.h>
|
2007-09-25 13:27:09 +00:00
|
|
|
|
2007-08-22 19:45:06 +00:00
|
|
|
/*
|
|
|
|
* Return the full scan size for a bitmap.
|
2007-10-19 23:21:45 +00:00
|
|
|
*
|
2008-11-18 05:36:19 +00:00
|
|
|
* Based on Wine, Utils.c and Windows Graphics Prog pg 595, SDK amvideo.h.
|
2007-08-22 19:45:06 +00:00
|
|
|
*/
|
|
|
|
UINT
|
|
|
|
FASTCALL
|
|
|
|
DIB_BitmapMaxBitsSize( PBITMAPINFO Info, UINT ScanLines )
|
|
|
|
{
|
|
|
|
UINT MaxBits = 0;
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2008-11-18 05:36:19 +00:00
|
|
|
if (!Info) return 0;
|
|
|
|
|
2007-08-22 19:45:06 +00:00
|
|
|
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;
|
2007-10-19 23:21:45 +00:00
|
|
|
// Planes are over looked by Yuan. I guess assumed always 1.
|
2007-08-22 19:45:06 +00:00
|
|
|
MaxBits = Info->bmiHeader.biBitCount * Info->bmiHeader.biPlanes * Info->bmiHeader.biWidth;
|
|
|
|
}
|
2007-08-23 22:29:37 +00:00
|
|
|
MaxBits = ((MaxBits + 31) & ~31 ) / 8; // From Yuan, ScanLineSize = (Width * bitcount + 31)/32
|
2007-08-22 19:45:06 +00:00
|
|
|
return (MaxBits * ScanLines); // ret the full Size.
|
|
|
|
}
|
|
|
|
|
2008-11-18 05:36:19 +00:00
|
|
|
UINT
|
|
|
|
FASTCALL
|
2010-06-09 00:18:29 +00:00
|
|
|
DIB_BitmapBitsSize( CONST BITMAPINFO* Info )
|
2008-11-18 05:36:19 +00:00
|
|
|
{
|
|
|
|
UINT Ret;
|
|
|
|
|
|
|
|
if (!Info) return 0;
|
|
|
|
|
|
|
|
if ( Info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
|
|
|
|
{
|
|
|
|
PBITMAPCOREHEADER Core = (PBITMAPCOREHEADER)Info;
|
2010-06-09 00:08:50 +00:00
|
|
|
Ret = Core->bcHeight *
|
2008-11-18 05:36:19 +00:00
|
|
|
((Core->bcWidth * Core->bcPlanes * Core->bcBitCount + 31) & ~31 ) / 8;
|
|
|
|
}
|
|
|
|
else /* assume BITMAPINFOHEADER */
|
|
|
|
{
|
2010-06-09 00:08:50 +00:00
|
|
|
if ((Info->bmiHeader.biCompression) &&
|
2008-11-18 05:36:19 +00:00
|
|
|
(Info->bmiHeader.biCompression != BI_BITFIELDS))
|
|
|
|
return Info->bmiHeader.biSizeImage;
|
|
|
|
// Make Height positive always....
|
2010-06-09 00:08:50 +00:00
|
|
|
Ret = abs(Info->bmiHeader.biHeight) *
|
2008-11-18 05:36:19 +00:00
|
|
|
((Info->bmiHeader.biWidth * Info->bmiHeader.biPlanes * Info->bmiHeader.biBitCount + 31) & ~31 ) / 8;
|
|
|
|
}
|
|
|
|
return Ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-30 22:37:42 +00:00
|
|
|
/*
|
|
|
|
* DIB_GetBitmapInfo is complete copy of wine cvs 2/9-2006
|
|
|
|
* from file dib.c from gdi32.dll or orginal version
|
|
|
|
* did not calc the info right for some headers.
|
|
|
|
*/
|
|
|
|
INT
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2008-03-30 22:37:42 +00:00
|
|
|
DIB_GetBitmapInfo(const BITMAPINFOHEADER *header,
|
2008-09-25 18:10:23 +00:00
|
|
|
PLONG width,
|
|
|
|
PLONG height,
|
|
|
|
PWORD planes,
|
|
|
|
PWORD bpp,
|
|
|
|
PLONG compr,
|
|
|
|
PLONG size )
|
2008-03-30 22:37:42 +00:00
|
|
|
{
|
|
|
|
if (header->biSize == sizeof(BITMAPCOREHEADER))
|
|
|
|
{
|
|
|
|
BITMAPCOREHEADER *core = (BITMAPCOREHEADER *)header;
|
|
|
|
*width = core->bcWidth;
|
|
|
|
*height = core->bcHeight;
|
|
|
|
*planes = core->bcPlanes;
|
|
|
|
*bpp = core->bcBitCount;
|
|
|
|
*compr = 0;
|
|
|
|
*size = 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (header->biSize == sizeof(BITMAPINFOHEADER))
|
|
|
|
{
|
|
|
|
*width = header->biWidth;
|
|
|
|
*height = header->biHeight;
|
|
|
|
*planes = header->biPlanes;
|
|
|
|
*bpp = header->biBitCount;
|
|
|
|
*compr = header->biCompression;
|
|
|
|
*size = header->biSizeImage;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (header->biSize == sizeof(BITMAPV4HEADER))
|
|
|
|
{
|
|
|
|
BITMAPV4HEADER *v4hdr = (BITMAPV4HEADER *)header;
|
|
|
|
*width = v4hdr->bV4Width;
|
|
|
|
*height = v4hdr->bV4Height;
|
|
|
|
*planes = v4hdr->bV4Planes;
|
|
|
|
*bpp = v4hdr->bV4BitCount;
|
|
|
|
*compr = v4hdr->bV4V4Compression;
|
|
|
|
*size = v4hdr->bV4SizeImage;
|
|
|
|
return 4;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (header->biSize == sizeof(BITMAPV5HEADER))
|
|
|
|
{
|
|
|
|
BITMAPV5HEADER *v5hdr = (BITMAPV5HEADER *)header;
|
|
|
|
*width = v5hdr->bV5Width;
|
|
|
|
*height = v5hdr->bV5Height;
|
|
|
|
*planes = v5hdr->bV5Planes;
|
|
|
|
*bpp = v5hdr->bV5BitCount;
|
|
|
|
*compr = v5hdr->bV5Compression;
|
|
|
|
*size = v5hdr->bV5SizeImage;
|
|
|
|
return 5;
|
|
|
|
}
|
|
|
|
DPRINT("(%ld): wrong size for header\n", header->biSize );
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2008-11-30 13:17:19 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
WINAPI
|
|
|
|
GdiGetBitmapBitsSize(BITMAPINFO *lpbmi)
|
|
|
|
{
|
|
|
|
int retSize;
|
2010-06-09 00:08:50 +00:00
|
|
|
|
2008-11-30 13:17:19 +00:00
|
|
|
if (lpbmi->bmiHeader.biSize == FIELD_OFFSET(BITMAPINFOHEADER, biPlanes))
|
|
|
|
{
|
|
|
|
/* Calc the bits Size and align it*/
|
2010-06-09 00:08:50 +00:00
|
|
|
retSize = HIWORD(lpbmi->bmiHeader.biWidth) * ((LOWORD(lpbmi->bmiHeader.biWidth) *
|
|
|
|
LOWORD(lpbmi->bmiHeader.biHeight) * HIWORD(lpbmi->bmiHeader.biHeight) + 31)
|
2008-11-30 13:17:19 +00:00
|
|
|
& -32) / 8;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ( (lpbmi->bmiHeader.biCompression == BI_BITFIELDS) ||
|
|
|
|
(lpbmi->bmiHeader.biCompression == BI_RGB))
|
|
|
|
{
|
|
|
|
if (lpbmi->bmiHeader.biHeight >=0 )
|
|
|
|
{
|
|
|
|
/* Calc the bits Size and align it*/
|
2010-06-09 00:08:50 +00:00
|
|
|
retSize = lpbmi->bmiHeader.biHeight * ((lpbmi->bmiHeader.biWidth *
|
2008-11-30 13:17:19 +00:00
|
|
|
lpbmi->bmiHeader.biPlanes * lpbmi->bmiHeader.biBitCount + 31) & -32) / 8;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Make height postiive if it negitve then calc the bits Size and align it*/
|
2010-06-09 00:08:50 +00:00
|
|
|
retSize = (-lpbmi->bmiHeader.biHeight) * ((lpbmi->bmiHeader.biWidth *
|
2008-11-30 13:17:19 +00:00
|
|
|
lpbmi->bmiHeader.biPlanes * lpbmi->bmiHeader.biBitCount + 31) & -32) / 8;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
retSize = lpbmi->bmiHeader.biSizeImage;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return retSize;
|
|
|
|
}
|
|
|
|
|
2005-07-31 12:11:56 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2008-11-30 11:42:05 +00:00
|
|
|
HBITMAP WINAPI
|
2005-07-31 12:11:56 +00:00
|
|
|
CreateDIBSection(
|
|
|
|
HDC hDC,
|
|
|
|
CONST BITMAPINFO *BitmapInfo,
|
|
|
|
UINT Usage,
|
|
|
|
VOID **Bits,
|
|
|
|
HANDLE hSection,
|
|
|
|
DWORD dwOffset)
|
|
|
|
{
|
|
|
|
PBITMAPINFO pConvertedInfo;
|
|
|
|
UINT ConvertedInfoSize;
|
|
|
|
HBITMAP hBitmap = NULL;
|
2008-11-18 05:36:19 +00:00
|
|
|
PVOID bmBits = NULL;
|
2005-07-31 12:11:56 +00:00
|
|
|
|
|
|
|
pConvertedInfo = ConvertBitmapInfo(BitmapInfo, Usage,
|
|
|
|
&ConvertedInfoSize, FALSE);
|
|
|
|
if (pConvertedInfo)
|
2008-11-18 05:36:19 +00:00
|
|
|
{ // Verify header due to converted may == info.
|
|
|
|
if ( pConvertedInfo->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER) )
|
|
|
|
{
|
2010-06-09 00:08:50 +00:00
|
|
|
if ( pConvertedInfo->bmiHeader.biCompression == BI_JPEG ||
|
2008-11-18 05:36:19 +00:00
|
|
|
pConvertedInfo->bmiHeader.biCompression == BI_PNG )
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
bmBits = Bits;
|
|
|
|
hBitmap = NtGdiCreateDIBSection( hDC,
|
|
|
|
hSection,
|
|
|
|
dwOffset,
|
|
|
|
pConvertedInfo,
|
|
|
|
Usage,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
&bmBits);
|
2005-07-31 12:11:56 +00:00
|
|
|
if (BitmapInfo != pConvertedInfo)
|
|
|
|
RtlFreeHeap(RtlGetProcessHeap(), 0, pConvertedInfo);
|
2008-11-18 05:36:19 +00:00
|
|
|
|
|
|
|
if (!hBitmap)
|
|
|
|
{
|
|
|
|
bmBits = NULL;
|
|
|
|
}
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
|
|
|
|
2008-11-18 05:36:19 +00:00
|
|
|
if (Bits) *Bits = bmBits;
|
|
|
|
|
2005-07-31 12:11:56 +00:00
|
|
|
return hBitmap;
|
|
|
|
}
|
|
|
|
|
2008-06-07 00:51:38 +00:00
|
|
|
|
2005-12-28 20:31:44 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
BOOL
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2005-12-28 20:31:44 +00:00
|
|
|
BitBlt(HDC hdcDest, /* handle to destination DC */
|
|
|
|
int nXOriginDest, /* x-coord of destination upper-left corner */
|
|
|
|
int nYOriginDest, /* y-coord of destination upper-left corner */
|
|
|
|
int nWidthDest, /* width of destination rectangle */
|
|
|
|
int nHeightDest, /* height of destination rectangle */
|
|
|
|
HDC hdcSrc, /* handle to source DC */
|
|
|
|
int nXSrc, /* x-coordinate of source upper-left corner */
|
|
|
|
int nYSrc, /* y-coordinate of source upper-left corner */
|
|
|
|
DWORD dwRop) /* raster operation code */
|
|
|
|
{
|
2008-06-07 00:51:38 +00:00
|
|
|
/* use patBlt for no source blt Like windows does */
|
|
|
|
if (!ROP_USES_SOURCE(dwRop))
|
|
|
|
{
|
|
|
|
return PatBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, dwRop);
|
|
|
|
}
|
|
|
|
|
2005-12-28 20:31:44 +00:00
|
|
|
return NtGdiBitBlt(hdcDest,
|
|
|
|
nXOriginDest,
|
|
|
|
nYOriginDest,
|
|
|
|
nWidthDest,
|
|
|
|
nHeightDest,
|
|
|
|
hdcSrc,
|
|
|
|
nXSrc,
|
|
|
|
nYSrc,
|
|
|
|
dwRop,
|
|
|
|
0,
|
|
|
|
0);
|
|
|
|
}
|
|
|
|
|
2005-07-31 12:11:56 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2008-11-30 11:42:05 +00:00
|
|
|
BOOL WINAPI
|
2005-07-31 12:11:56 +00:00
|
|
|
StretchBlt(
|
|
|
|
HDC hdcDest, /* handle to destination DC */
|
|
|
|
int nXOriginDest, /* x-coord of destination upper-left corner */
|
|
|
|
int nYOriginDest, /* y-coord of destination upper-left corner */
|
|
|
|
int nWidthDest, /* width of destination rectangle */
|
|
|
|
int nHeightDest, /* height of destination rectangle */
|
|
|
|
HDC hdcSrc, /* handle to source DC */
|
|
|
|
int nXOriginSrc, /* x-coord of source upper-left corner */
|
|
|
|
int nYOriginSrc, /* y-coord of source upper-left corner */
|
|
|
|
int nWidthSrc, /* width of source rectangle */
|
|
|
|
int nHeightSrc, /* height of source rectangle */
|
|
|
|
DWORD dwRop) /* raster operation code */
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2005-07-31 12:11:56 +00:00
|
|
|
{
|
|
|
|
if ((nWidthDest != nWidthSrc) || (nHeightDest != nHeightSrc))
|
|
|
|
{
|
|
|
|
return NtGdiStretchBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest,
|
|
|
|
nHeightDest, hdcSrc, nXOriginSrc, nYOriginSrc,
|
2005-12-28 20:31:44 +00:00
|
|
|
nWidthSrc, nHeightSrc, dwRop, 0);
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2005-07-31 12:11:56 +00:00
|
|
|
return NtGdiBitBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest,
|
2005-12-28 20:31:44 +00:00
|
|
|
nHeightDest, hdcSrc, nXOriginSrc, nYOriginSrc, dwRop, 0, 0);
|
2005-07-31 12:11:56 +00:00
|
|
|
}
|
2007-07-26 15:20:29 +00:00
|
|
|
|
2008-11-18 05:36:19 +00:00
|
|
|
/*
|
|
|
|
* @unimplemented
|
|
|
|
*/
|
2008-11-30 11:42:05 +00:00
|
|
|
HBITMAP WINAPI
|
2008-11-18 05:36:19 +00:00
|
|
|
CreateBitmap(INT Width,
|
|
|
|
INT Height,
|
|
|
|
UINT Planes,
|
|
|
|
UINT BitsPixel,
|
2010-03-29 02:03:41 +00:00
|
|
|
CONST VOID* pUnsafeBits)
|
2008-11-18 05:36:19 +00:00
|
|
|
{
|
|
|
|
/* FIXME some part should be done in user mode */
|
|
|
|
if (Width && Height)
|
|
|
|
{
|
|
|
|
return NtGdiCreateBitmap(Width, Height, Planes, BitsPixel, (LPBYTE) pUnsafeBits);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Return 1x1 bitmap */
|
|
|
|
return GetStockObject(DEFAULT_BITMAP);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-07-26 15:20:29 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
HBITMAP WINAPI
|
|
|
|
CreateBitmapIndirect(const BITMAP *pbm)
|
|
|
|
{
|
2008-05-11 08:20:18 +00:00
|
|
|
HBITMAP bitmap = NULL;
|
|
|
|
|
|
|
|
/* Note windows xp/2003 does not check if pbm is NULL or not */
|
|
|
|
if ( (pbm->bmWidthBytes != 0) &&
|
|
|
|
(!(pbm->bmWidthBytes & 1)) )
|
|
|
|
|
2007-07-26 15:20:29 +00:00
|
|
|
{
|
2010-06-09 00:08:50 +00:00
|
|
|
|
2008-05-11 08:20:18 +00:00
|
|
|
bitmap = CreateBitmap(pbm->bmWidth,
|
|
|
|
pbm->bmHeight,
|
|
|
|
pbm->bmPlanes,
|
|
|
|
pbm->bmBitsPixel,
|
|
|
|
pbm->bmBits);
|
2007-07-26 15:20:29 +00:00
|
|
|
}
|
2008-05-11 10:41:06 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
|
|
}
|
2008-05-11 08:20:18 +00:00
|
|
|
|
|
|
|
return bitmap;
|
2007-07-26 15:20:29 +00:00
|
|
|
}
|
2007-07-26 15:59:44 +00:00
|
|
|
|
|
|
|
HBITMAP WINAPI
|
|
|
|
CreateDiscardableBitmap(
|
|
|
|
HDC hDC,
|
|
|
|
INT Width,
|
|
|
|
INT Height)
|
|
|
|
{
|
2007-08-23 15:03:13 +00:00
|
|
|
return CreateCompatibleBitmap(hDC, Width, Height);
|
2007-07-26 15:59:44 +00:00
|
|
|
}
|
2007-08-19 23:49:47 +00:00
|
|
|
|
|
|
|
|
2007-08-23 14:02:10 +00:00
|
|
|
HBITMAP WINAPI
|
|
|
|
CreateCompatibleBitmap(
|
|
|
|
HDC hDC,
|
|
|
|
INT Width,
|
|
|
|
INT Height)
|
|
|
|
{
|
2008-11-18 05:36:19 +00:00
|
|
|
PDC_ATTR pDc_Attr;
|
|
|
|
HBITMAP hBmp = NULL;
|
|
|
|
DIBSECTION dibs;
|
|
|
|
|
|
|
|
if (!GdiGetHandleUserData(hDC, GDI_OBJECT_TYPE_DC, (PVOID)&pDc_Attr))
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
if ( !Width || !Height )
|
|
|
|
return GetStockObject(DEFAULT_BITMAP);
|
|
|
|
|
|
|
|
if (!(pDc_Attr->ulDirty_ & DC_DIBSECTION))
|
|
|
|
{
|
|
|
|
return NtGdiCreateCompatibleBitmap(hDC, Width, Height);
|
|
|
|
}
|
|
|
|
|
|
|
|
hBmp = NtGdiGetDCObject(hDC, GDI_OBJECT_TYPE_BITMAP);
|
|
|
|
|
|
|
|
if ( GetObjectA(hBmp, sizeof(DIBSECTION), &dibs) != sizeof(DIBSECTION) )
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
if ( dibs.dsBm.bmBitsPixel <= 8 )
|
|
|
|
GetDIBColorTable(hDC, 0, 256, (RGBQUAD *)&dibs.dsBitfields);
|
|
|
|
|
|
|
|
dibs.dsBmih.biWidth = Width;
|
|
|
|
dibs.dsBmih.biHeight = Height;
|
|
|
|
|
|
|
|
return CreateDIBSection(hDC, (CONST BITMAPINFO *)&dibs.dsBmih, 0, NULL, NULL, 0);
|
2007-08-23 14:02:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-19 23:21:45 +00:00
|
|
|
INT
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2007-08-22 19:45:06 +00:00
|
|
|
GetDIBits(
|
|
|
|
HDC hDC,
|
|
|
|
HBITMAP hbmp,
|
|
|
|
UINT uStartScan,
|
|
|
|
UINT cScanLines,
|
|
|
|
LPVOID lpvBits,
|
|
|
|
LPBITMAPINFO lpbmi,
|
2007-09-25 13:27:09 +00:00
|
|
|
UINT uUsage)
|
2007-08-22 19:45:06 +00:00
|
|
|
{
|
2008-11-18 05:36:19 +00:00
|
|
|
INT Ret = 0;
|
|
|
|
UINT cjBmpScanSize;
|
|
|
|
PVOID pvSafeBits = lpvBits;
|
2007-09-25 13:27:09 +00:00
|
|
|
|
2008-11-18 05:36:19 +00:00
|
|
|
if (!hDC || !GdiIsHandleValid((HGDIOBJ)hDC))
|
|
|
|
{
|
|
|
|
GdiSetLastError(ERROR_INVALID_PARAMETER);
|
|
|
|
return Ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
cjBmpScanSize = DIB_BitmapMaxBitsSize(lpbmi, cScanLines);
|
|
|
|
|
|
|
|
if ( lpvBits )
|
|
|
|
{
|
|
|
|
if ( lpbmi )
|
|
|
|
{
|
|
|
|
if ( lpbmi->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER) )
|
|
|
|
{
|
2010-06-09 00:08:50 +00:00
|
|
|
if ( lpbmi->bmiHeader.biCompression == BI_JPEG ||
|
2008-11-18 05:36:19 +00:00
|
|
|
lpbmi->bmiHeader.biCompression == BI_PNG )
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
|
|
return Ret;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-03-05 12:22:35 +00:00
|
|
|
|
|
|
|
if ((ULONG)lpvBits & (sizeof(DWORD) - 1))
|
|
|
|
{
|
|
|
|
pvSafeBits = RtlAllocateHeap(RtlGetProcessHeap(), 0, cjBmpScanSize);
|
|
|
|
if (!pvSafeBits)
|
|
|
|
return Ret;
|
|
|
|
}
|
2008-11-18 05:36:19 +00:00
|
|
|
}
|
2007-09-25 13:27:09 +00:00
|
|
|
|
2008-11-18 05:36:19 +00:00
|
|
|
Ret = NtGdiGetDIBitsInternal(hDC,
|
|
|
|
hbmp,
|
|
|
|
uStartScan,
|
|
|
|
cScanLines,
|
|
|
|
pvSafeBits,
|
|
|
|
lpbmi,
|
|
|
|
uUsage,
|
|
|
|
cjBmpScanSize,
|
|
|
|
0);
|
2009-03-05 12:22:35 +00:00
|
|
|
if (lpvBits != pvSafeBits)
|
2008-11-18 05:36:19 +00:00
|
|
|
{
|
2009-03-05 12:22:35 +00:00
|
|
|
if (Ret)
|
|
|
|
{
|
|
|
|
RtlCopyMemory(lpvBits, pvSafeBits, cjBmpScanSize);
|
|
|
|
}
|
2008-11-18 05:36:19 +00:00
|
|
|
RtlFreeHeap(RtlGetProcessHeap(), 0, pvSafeBits);
|
|
|
|
}
|
|
|
|
return Ret;
|
2007-08-22 19:45:06 +00:00
|
|
|
}
|
2008-03-30 22:37:42 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
HBITMAP
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2008-03-30 22:37:42 +00:00
|
|
|
CreateDIBitmap( HDC hDC,
|
|
|
|
const BITMAPINFOHEADER *Header,
|
|
|
|
DWORD Init,
|
|
|
|
LPCVOID Bits,
|
|
|
|
const BITMAPINFO *Data,
|
|
|
|
UINT ColorUse)
|
|
|
|
{
|
2008-11-18 05:36:19 +00:00
|
|
|
LONG width, height, compr, dibsize;
|
|
|
|
WORD planes, bpp;
|
|
|
|
// PDC_ATTR pDc_Attr;
|
2010-06-10 14:32:05 +00:00
|
|
|
UINT InfoSize = 0;
|
|
|
|
UINT cjBmpScanSize = 0;
|
2008-11-18 05:36:19 +00:00
|
|
|
HBITMAP hBmp;
|
2010-06-10 12:58:52 +00:00
|
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
2008-11-18 05:36:19 +00:00
|
|
|
|
2009-05-20 07:51:22 +00:00
|
|
|
if (!Header) return 0;
|
|
|
|
|
2008-11-18 05:36:19 +00:00
|
|
|
if (DIB_GetBitmapInfo(Header, &width, &height, &planes, &bpp, &compr, &dibsize) == -1)
|
|
|
|
{
|
|
|
|
GdiSetLastError(ERROR_INVALID_PARAMETER);
|
|
|
|
return NULL;
|
|
|
|
}
|
2008-03-30 22:37:42 +00:00
|
|
|
|
2008-11-18 05:36:19 +00:00
|
|
|
// For Icm support.
|
|
|
|
// GdiGetHandleUserData(hdc, GDI_OBJECT_TYPE_DC, (PVOID)&pDc_Attr))
|
|
|
|
|
2010-06-10 14:32:05 +00:00
|
|
|
if(Data)
|
2010-06-10 12:58:52 +00:00
|
|
|
{
|
2010-06-10 14:32:05 +00:00
|
|
|
_SEH2_TRY
|
|
|
|
{
|
|
|
|
cjBmpScanSize = DIB_BitmapBitsSize(Data);
|
|
|
|
CalculateColorTableSize(&Data->bmiHeader, &ColorUse, &InfoSize);
|
|
|
|
InfoSize += Data->bmiHeader.biSize;
|
|
|
|
}
|
|
|
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
|
|
|
{
|
|
|
|
Status = _SEH2_GetExceptionCode();
|
|
|
|
}
|
|
|
|
_SEH2_END
|
2010-06-10 12:58:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if(!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
GdiSetLastError(ERROR_INVALID_PARAMETER);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
DPRINT("pBMI %x, Size bpp %d, dibsize %d, Conv %d, BSS %d\n", Data,bpp,dibsize,InfoSize,cjBmpScanSize);
|
2008-03-30 22:37:42 +00:00
|
|
|
|
2008-11-18 05:36:19 +00:00
|
|
|
if ( !width || !height )
|
|
|
|
hBmp = GetStockObject(DEFAULT_BITMAP);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
hBmp = NtGdiCreateDIBitmapInternal(hDC,
|
|
|
|
width,
|
|
|
|
height,
|
|
|
|
Init,
|
2010-06-09 00:08:50 +00:00
|
|
|
(LPBYTE)Bits,
|
|
|
|
(LPBITMAPINFO)Data,
|
2008-11-18 05:36:19 +00:00
|
|
|
ColorUse,
|
2010-06-10 12:58:52 +00:00
|
|
|
InfoSize,
|
2008-11-18 05:36:19 +00:00
|
|
|
cjBmpScanSize,
|
|
|
|
0,
|
|
|
|
0);
|
|
|
|
}
|
|
|
|
return hBmp;
|
2008-03-30 22:37:42 +00:00
|
|
|
}
|
|
|
|
|
2008-11-17 13:55:00 +00:00
|
|
|
#if 0 // FIXME!!! This is a victim of the Win32k Initialization BUG!!!!!
|
2008-04-18 23:51:29 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
INT
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2008-04-18 23:51:29 +00:00
|
|
|
SetDIBits(HDC hDC,
|
|
|
|
HBITMAP hBitmap,
|
|
|
|
UINT uStartScan,
|
|
|
|
UINT cScanLines,
|
|
|
|
CONST VOID *lpvBits,
|
|
|
|
CONST BITMAPINFO *lpbmi,
|
|
|
|
UINT fuColorUse)
|
|
|
|
{
|
|
|
|
HDC hDCc, SavehDC, nhDC;
|
|
|
|
DWORD dwWidth, dwHeight;
|
|
|
|
HGDIOBJ hOldBitmap;
|
|
|
|
HPALETTE hPal = NULL;
|
|
|
|
INT LinesCopied = 0;
|
|
|
|
BOOL newDC = FALSE;
|
|
|
|
|
|
|
|
if ( !lpvBits || (GDI_HANDLE_GET_TYPE(hBitmap) != GDI_OBJECT_TYPE_BITMAP) )
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if ( lpbmi )
|
|
|
|
{
|
|
|
|
if ( lpbmi->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER) )
|
|
|
|
{
|
|
|
|
if ( lpbmi->bmiHeader.biCompression == BI_JPEG || lpbmi->bmiHeader.biCompression == BI_PNG )
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
hDCc = NtGdiGetDCforBitmap(hBitmap);
|
|
|
|
SavehDC = hDCc;
|
|
|
|
if ( !hDCc )
|
|
|
|
{
|
|
|
|
nhDC = CreateCompatibleDC(hDC);
|
|
|
|
if ( !nhDC ) return 0;
|
|
|
|
newDC = TRUE;
|
|
|
|
SavehDC = nhDC;
|
|
|
|
}
|
|
|
|
else if ( !SaveDC(hDCc) )
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
hOldBitmap = SelectObject(SavehDC, hBitmap);
|
|
|
|
|
|
|
|
if ( hOldBitmap )
|
|
|
|
{
|
2010-06-09 00:08:50 +00:00
|
|
|
if ( hDC )
|
2008-04-18 23:51:29 +00:00
|
|
|
hPal = SelectPalette(SavehDC, (HPALETTE)GetDCObject(hDC, GDI_OBJECT_TYPE_PALETTE), FALSE);
|
|
|
|
|
|
|
|
if ( lpbmi->bmiHeader.biSize < sizeof(BITMAPINFOHEADER))
|
|
|
|
{
|
|
|
|
PBITMAPCOREINFO pbci = (PBITMAPCOREINFO) lpbmi;
|
|
|
|
dwWidth = pbci->bmciHeader.bcWidth;
|
|
|
|
dwHeight = pbci->bmciHeader.bcHeight;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
dwWidth = lpbmi->bmiHeader.biWidth;
|
|
|
|
dwHeight = abs(lpbmi->bmiHeader.biHeight);
|
|
|
|
}
|
|
|
|
|
|
|
|
LinesCopied = SetDIBitsToDevice(SavehDC,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
dwWidth,
|
|
|
|
dwHeight,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
uStartScan,
|
|
|
|
cScanLines,
|
|
|
|
(void *)lpvBits,
|
|
|
|
(LPBITMAPINFO)lpbmi,
|
|
|
|
fuColorUse);
|
|
|
|
|
|
|
|
if ( hDC ) SelectPalette(SavehDC, hPal, FALSE);
|
|
|
|
|
|
|
|
SelectObject(SavehDC, hOldBitmap);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( newDC )
|
2008-04-19 02:20:36 +00:00
|
|
|
DeleteDC(SavehDC);
|
2008-04-18 23:51:29 +00:00
|
|
|
else
|
2008-04-19 02:20:36 +00:00
|
|
|
RestoreDC(SavehDC, -1);
|
2008-04-18 23:51:29 +00:00
|
|
|
|
|
|
|
return LinesCopied;
|
|
|
|
}
|
2008-04-19 19:00:34 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
INT
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2008-04-19 19:00:34 +00:00
|
|
|
SetDIBits(HDC hdc,
|
|
|
|
HBITMAP hbmp,
|
|
|
|
UINT uStartScan,
|
|
|
|
UINT cScanLines,
|
|
|
|
CONST VOID *lpvBits,
|
|
|
|
CONST BITMAPINFO *lpbmi,
|
|
|
|
UINT fuColorUse)
|
|
|
|
{
|
2008-11-18 16:07:54 +00:00
|
|
|
PBITMAPINFO pConvertedInfo;
|
|
|
|
UINT ConvertedInfoSize;
|
2008-11-18 05:36:19 +00:00
|
|
|
INT LinesCopied = 0;
|
2008-11-18 16:07:54 +00:00
|
|
|
UINT cjBmpScanSize = 0;
|
|
|
|
PVOID pvSafeBits = (PVOID)lpvBits;
|
2008-11-18 05:36:19 +00:00
|
|
|
|
|
|
|
// 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;
|
|
|
|
|
2008-11-18 16:07:54 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2008-11-18 05:36:19 +00:00
|
|
|
LinesCopied = NtGdiSetDIBits( hdc,
|
|
|
|
hbmp,
|
|
|
|
uStartScan,
|
|
|
|
cScanLines,
|
2008-11-18 16:07:54 +00:00
|
|
|
pvSafeBits,
|
|
|
|
pConvertedInfo,
|
2008-11-18 05:36:19 +00:00
|
|
|
fuColorUse);
|
|
|
|
|
2008-11-18 16:07:54 +00:00
|
|
|
if ( lpvBits != pvSafeBits)
|
|
|
|
RtlFreeHeap(RtlGetProcessHeap(), 0, pvSafeBits);
|
|
|
|
if (lpbmi != pConvertedInfo)
|
|
|
|
RtlFreeHeap(RtlGetProcessHeap(), 0, pConvertedInfo);
|
2008-11-18 05:36:19 +00:00
|
|
|
return LinesCopied;
|
2008-04-19 19:00:34 +00:00
|
|
|
}
|
2008-04-18 23:51:29 +00:00
|
|
|
|
2008-04-19 02:20:36 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
INT
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2008-04-19 02:20:36 +00:00
|
|
|
SetDIBitsToDevice(
|
2008-11-18 05:36:19 +00:00
|
|
|
HDC hdc,
|
2008-04-19 02:20:36 +00:00
|
|
|
int XDest,
|
|
|
|
int YDest,
|
|
|
|
DWORD Width,
|
|
|
|
DWORD Height,
|
|
|
|
int XSrc,
|
|
|
|
int YSrc,
|
|
|
|
UINT StartScan,
|
|
|
|
UINT ScanLines,
|
|
|
|
CONST VOID *Bits,
|
|
|
|
CONST BITMAPINFO *lpbmi,
|
|
|
|
UINT ColorUse)
|
|
|
|
{
|
2008-11-18 05:36:19 +00:00
|
|
|
PDC_ATTR pDc_Attr;
|
|
|
|
PBITMAPINFO pConvertedInfo;
|
|
|
|
UINT ConvertedInfoSize;
|
|
|
|
INT LinesCopied = 0;
|
|
|
|
UINT cjBmpScanSize = 0;
|
|
|
|
PVOID pvSafeBits = (PVOID)Bits;
|
|
|
|
|
|
|
|
if ( !ScanLines || !lpbmi || !Bits )
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if ( ColorUse && ColorUse != DIB_PAL_COLORS && ColorUse != DIB_PAL_COLORS+1 )
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
pConvertedInfo = ConvertBitmapInfo(lpbmi, ColorUse,
|
|
|
|
&ConvertedInfoSize, FALSE);
|
|
|
|
if (!pConvertedInfo)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
// Handle something other than a normal dc object.
|
|
|
|
if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
|
|
|
|
{
|
|
|
|
if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
|
|
|
|
return MFDRV_SetDIBitsToDevice( hdc,
|
|
|
|
XDest,
|
|
|
|
YDest,
|
|
|
|
Width,
|
|
|
|
Height,
|
|
|
|
XSrc,
|
|
|
|
YSrc,
|
|
|
|
StartScan,
|
|
|
|
ScanLines,
|
|
|
|
Bits,
|
|
|
|
lpbmi,
|
|
|
|
ColorUse);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
PLDC pLDC = GdiGetLDC(hdc);
|
|
|
|
if ( !pLDC )
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (pLDC->iType == LDC_EMFLDC)
|
|
|
|
{
|
|
|
|
return EMFDRV_SetDIBitsToDevice(hdc,
|
|
|
|
XDest,
|
|
|
|
YDest,
|
|
|
|
Width,
|
|
|
|
Height,
|
|
|
|
XSrc,
|
|
|
|
YSrc,
|
|
|
|
StartScan,
|
|
|
|
ScanLines,
|
|
|
|
Bits,
|
|
|
|
lpbmi,
|
|
|
|
ColorUse);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
cjBmpScanSize = DIB_BitmapMaxBitsSize((LPBITMAPINFO)lpbmi, ScanLines);
|
|
|
|
|
|
|
|
if ( Bits )
|
|
|
|
{
|
|
|
|
pvSafeBits = RtlAllocateHeap(GetProcessHeap(), 0, cjBmpScanSize);
|
|
|
|
if (pvSafeBits)
|
|
|
|
RtlCopyMemory( pvSafeBits, Bits, cjBmpScanSize);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!GdiGetHandleUserData(hdc, GDI_OBJECT_TYPE_DC, (PVOID)&pDc_Attr))
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
if ( !pDc_Attr ||
|
|
|
|
((pConvertedInfo->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER)) &&
|
2010-06-09 00:08:50 +00:00
|
|
|
(pConvertedInfo->bmiHeader.biCompression == BI_JPEG ||
|
2008-11-18 05:36:19 +00:00
|
|
|
pConvertedInfo->bmiHeader.biCompression == BI_PNG )) )*/
|
|
|
|
{
|
|
|
|
LinesCopied = NtGdiSetDIBitsToDeviceInternal( hdc,
|
|
|
|
XDest,
|
|
|
|
YDest,
|
|
|
|
Width,
|
|
|
|
Height,
|
|
|
|
XSrc,
|
|
|
|
YSrc,
|
|
|
|
StartScan,
|
|
|
|
ScanLines,
|
|
|
|
(LPBYTE)pvSafeBits,
|
|
|
|
(LPBITMAPINFO)pConvertedInfo,
|
|
|
|
ColorUse,
|
|
|
|
cjBmpScanSize,
|
|
|
|
ConvertedInfoSize,
|
|
|
|
TRUE,
|
|
|
|
NULL);
|
|
|
|
}
|
2008-11-18 16:07:54 +00:00
|
|
|
if ( Bits != pvSafeBits)
|
2008-11-18 05:36:19 +00:00
|
|
|
RtlFreeHeap(RtlGetProcessHeap(), 0, pvSafeBits);
|
|
|
|
if (lpbmi != pConvertedInfo)
|
|
|
|
RtlFreeHeap(RtlGetProcessHeap(), 0, pConvertedInfo);
|
2010-06-09 00:08:50 +00:00
|
|
|
|
2008-11-18 05:36:19 +00:00
|
|
|
return LinesCopied;
|
2008-04-19 02:20:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-11-17 13:55:00 +00:00
|
|
|
/*
|
|
|
|
* @unimplemented
|
|
|
|
*/
|
|
|
|
int
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2008-11-17 13:55:00 +00:00
|
|
|
StretchDIBits(HDC hdc,
|
|
|
|
int XDest,
|
|
|
|
int YDest,
|
|
|
|
int nDestWidth,
|
|
|
|
int nDestHeight,
|
|
|
|
int XSrc,
|
|
|
|
int YSrc,
|
|
|
|
int nSrcWidth,
|
|
|
|
int nSrcHeight,
|
|
|
|
CONST VOID *lpBits,
|
|
|
|
CONST BITMAPINFO *lpBitsInfo,
|
|
|
|
UINT iUsage,
|
|
|
|
DWORD dwRop)
|
|
|
|
|
|
|
|
{
|
2008-11-18 05:36:19 +00:00
|
|
|
PDC_ATTR pDc_Attr;
|
|
|
|
PBITMAPINFO pConvertedInfo = NULL;
|
|
|
|
UINT ConvertedInfoSize = 0;
|
|
|
|
INT LinesCopied = 0;
|
|
|
|
UINT cjBmpScanSize = 0;
|
|
|
|
PVOID pvSafeBits = NULL;
|
|
|
|
BOOL Hit = FALSE;
|
|
|
|
|
|
|
|
DPRINT("StretchDIBits %x : %x : %d\n", lpBits, lpBitsInfo, iUsage);
|
|
|
|
#if 0
|
|
|
|
// Handle something other than a normal dc object.
|
|
|
|
if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
|
|
|
|
{
|
|
|
|
if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
|
|
|
|
return MFDRV_StretchBlt( hdc,
|
|
|
|
XDest,
|
|
|
|
YDest,
|
|
|
|
nDestWidth,
|
|
|
|
nDestHeight,
|
|
|
|
XSrc,
|
|
|
|
YSrc,
|
|
|
|
nSrcWidth,
|
|
|
|
nSrcHeight,
|
|
|
|
lpBits,
|
|
|
|
lpBitsInfo,
|
|
|
|
iUsage,
|
|
|
|
dwRop);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
PLDC pLDC = GdiGetLDC(hdc);
|
|
|
|
if ( !pLDC )
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (pLDC->iType == LDC_EMFLDC)
|
|
|
|
{
|
|
|
|
return EMFDRV_StretchBlt(hdc,
|
|
|
|
XDest,
|
|
|
|
YDest,
|
|
|
|
nDestWidth,
|
|
|
|
nDestHeight,
|
|
|
|
XSrc,
|
|
|
|
YSrc,
|
|
|
|
nSrcWidth,
|
|
|
|
nSrcHeight,
|
|
|
|
lpBits,
|
|
|
|
lpBitsInfo,
|
|
|
|
iUsage,
|
|
|
|
dwRop);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
2010-08-05 21:03:35 +00:00
|
|
|
pConvertedInfo = ConvertBitmapInfo(lpBitsInfo, iUsage,
|
|
|
|
&ConvertedInfoSize, FALSE);
|
|
|
|
if (!pConvertedInfo)
|
|
|
|
{
|
2008-11-18 05:36:19 +00:00
|
|
|
return 0;
|
2010-08-05 21:03:35 +00:00
|
|
|
}
|
2008-11-18 05:36:19 +00:00
|
|
|
|
|
|
|
cjBmpScanSize = DIB_BitmapBitsSize((LPBITMAPINFO)pConvertedInfo);
|
|
|
|
|
|
|
|
if ( lpBits )
|
|
|
|
{
|
|
|
|
pvSafeBits = RtlAllocateHeap(GetProcessHeap(), 0, cjBmpScanSize);
|
|
|
|
if (pvSafeBits)
|
|
|
|
{
|
2008-11-30 19:28:11 +00:00
|
|
|
_SEH2_TRY
|
2008-11-18 05:36:19 +00:00
|
|
|
{
|
|
|
|
RtlCopyMemory( pvSafeBits, lpBits, cjBmpScanSize );
|
|
|
|
}
|
2008-11-30 19:28:11 +00:00
|
|
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
2008-11-18 05:36:19 +00:00
|
|
|
{
|
|
|
|
Hit = TRUE;
|
|
|
|
}
|
2008-11-30 19:28:11 +00:00
|
|
|
_SEH2_END
|
2008-11-18 05:36:19 +00:00
|
|
|
|
|
|
|
if (Hit)
|
|
|
|
{
|
|
|
|
// We don't die, we continue on with a allocated safe pointer to kernel
|
|
|
|
// space.....
|
|
|
|
DPRINT1("StretchDIBits fail to read BitMapInfo: %x or Bits: %x & Size: %d\n",pConvertedInfo,lpBits,cjBmpScanSize);
|
|
|
|
}
|
|
|
|
DPRINT("StretchDIBits Allocate Bits %d!!!\n", cjBmpScanSize);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!GdiGetHandleUserData(hdc, GDI_OBJECT_TYPE_DC, (PVOID)&pDc_Attr))
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
if ( !pDc_Attr ||
|
|
|
|
((pConvertedInfo->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER)) &&
|
2010-06-09 00:08:50 +00:00
|
|
|
(pConvertedInfo->bmiHeader.biCompression == BI_JPEG ||
|
2008-11-18 05:36:19 +00:00
|
|
|
pConvertedInfo->bmiHeader.biCompression == BI_PNG )) )*/
|
|
|
|
{
|
|
|
|
LinesCopied = NtGdiStretchDIBitsInternal( hdc,
|
|
|
|
XDest,
|
|
|
|
YDest,
|
|
|
|
nDestWidth,
|
|
|
|
nDestHeight,
|
|
|
|
XSrc,
|
|
|
|
YSrc,
|
|
|
|
nSrcWidth,
|
|
|
|
nSrcHeight,
|
|
|
|
pvSafeBits,
|
|
|
|
pConvertedInfo,
|
|
|
|
(DWORD)iUsage,
|
|
|
|
dwRop,
|
|
|
|
ConvertedInfoSize,
|
|
|
|
cjBmpScanSize,
|
|
|
|
NULL);
|
|
|
|
}
|
|
|
|
if ( pvSafeBits )
|
|
|
|
RtlFreeHeap(RtlGetProcessHeap(), 0, pvSafeBits);
|
|
|
|
if (lpBitsInfo != pConvertedInfo)
|
|
|
|
RtlFreeHeap(RtlGetProcessHeap(), 0, pConvertedInfo);
|
|
|
|
|
|
|
|
return LinesCopied;
|
2008-11-17 13:55:00 +00:00
|
|
|
}
|
2008-06-05 22:23:19 +00:00
|
|
|
|