Implement CreateBitmap using CreateBitmapIndirect so we can handle

funky alignment paddings.
SetLastError() on failure, documentation cleanup.
This commit is contained in:
Jon Griffiths 2004-11-22 18:18:21 +00:00 committed by Alexandre Julliard
parent 2443c7f6d3
commit 853cb86fa7
1 changed files with 77 additions and 57 deletions

View File

@ -52,7 +52,7 @@ static const struct gdi_obj_funcs bitmap_funcs =
* Return number of bytes taken by a scanline of 16-bit aligned Windows DDB
* data.
*/
static INT BITMAP_GetWidthBytes( INT bmWidth, INT bpp )
INT BITMAP_GetWidthBytes( INT bmWidth, INT bpp )
{
switch(bpp)
{
@ -98,60 +98,21 @@ static INT BITMAP_GetWidthBytes( INT bmWidth, INT bpp )
* Failure: 0
*/
HBITMAP WINAPI CreateBitmap( INT width, INT height, UINT planes,
UINT bpp, LPCVOID bits )
UINT bpp, LPCVOID bits )
{
BITMAPOBJ *bmp;
HBITMAP hbitmap;
BITMAP bm;
planes = (BYTE)planes;
bpp = (BYTE)bpp;
bm.bmType = 0;
bm.bmWidth = width;
bm.bmHeight = height;
bm.bmWidthBytes = BITMAP_GetWidthBytes( width, bpp );
bm.bmPlanes = planes;
bm.bmBitsPixel = bpp;
bm.bmBits = (LPVOID)bits;
/* Check parameters */
if (!height || !width)
{
height = 1;
width = 1;
planes = 1;
bpp = 1;
}
if (planes != 1) {
FIXME("planes = %d\n", planes);
return 0;
}
if (height < 0) height = -height;
if (width < 0) width = -width;
/* Create the BITMAPOBJ */
if (!(bmp = GDI_AllocObject( sizeof(BITMAPOBJ), BITMAP_MAGIC,
(HGDIOBJ *)&hbitmap, &bitmap_funcs )))
return 0;
TRACE("%dx%d, %d colors returning %p\n", width, height, 1 << (planes*bpp), hbitmap);
bmp->size.cx = 0;
bmp->size.cy = 0;
bmp->bitmap.bmType = 0;
bmp->bitmap.bmWidth = width;
bmp->bitmap.bmHeight = height;
bmp->bitmap.bmPlanes = planes;
bmp->bitmap.bmBitsPixel = bpp;
bmp->bitmap.bmWidthBytes = BITMAP_GetWidthBytes( width, bpp );
bmp->bitmap.bmBits = NULL;
bmp->funcs = NULL;
bmp->physBitmap = NULL;
bmp->dib = NULL;
bmp->segptr_bits = 0;
if (bits) /* Set bitmap bits */
SetBitmapBits( hbitmap, height * bmp->bitmap.bmWidthBytes,
bits );
GDI_ReleaseObj( hbitmap );
return hbitmap;
return CreateBitmapIndirect( &bm );
}
/******************************************************************************
* CreateCompatibleBitmap [GDI32.@]
*
@ -223,7 +184,7 @@ HBITMAP WINAPI CreateCompatibleBitmap( HDC hdc, INT width, INT height)
bi->bmiHeader.biCompression = bmp->dib->dsBmih.biCompression;
bi->bmiHeader.biSizeImage = 0;
bi->bmiHeader.biXPelsPerMeter = bmp->dib->dsBmih.biXPelsPerMeter;
bi->bmiHeader.biYPelsPerMeter = bmp->dib->dsBmih.biYPelsPerMeter;
bi->bmiHeader.biYPelsPerMeter = bmp->dib->dsBmih.biYPelsPerMeter;
bi->bmiHeader.biClrUsed = bmp->dib->dsBmih.biClrUsed;
bi->bmiHeader.biClrImportant = bmp->dib->dsBmih.biClrImportant;
@ -255,17 +216,76 @@ HBITMAP WINAPI CreateCompatibleBitmap( HDC hdc, INT width, INT height)
/******************************************************************************
* CreateBitmapIndirect [GDI32.@]
*
* Creates a bitmap with the specifies info.
* Creates a bitmap with the specified info.
*
* PARAMS
* bmp [I] Pointer to the bitmap info describing the bitmap
*
* RETURNS
* Success: Handle to bitmap
* Failure: NULL
* Failure: NULL. Use GetLastError() to determine the cause.
*
* NOTES
* If a width or height of 0 are given, a 1x1 monochrome bitmap is returned.
*/
HBITMAP WINAPI CreateBitmapIndirect(
const BITMAP * bmp) /* [in] Pointer to the bitmap data */
HBITMAP WINAPI CreateBitmapIndirect( const BITMAP *bmp )
{
return CreateBitmap( bmp->bmWidth, bmp->bmHeight, bmp->bmPlanes,
bmp->bmBitsPixel, bmp->bmBits );
BITMAP bm;
BITMAPOBJ *bmpobj;
HBITMAP hbitmap;
if (!bmp || bmp->bmType || bmp->bmPlanes != 1)
{
if (bmp && bmp->bmPlanes != 1)
FIXME("planes = %d\n", bmp->bmPlanes);
SetLastError( ERROR_INVALID_PARAMETER );
return NULL;
}
bm = *bmp;
if (!bm.bmWidth || !bm.bmHeight)
{
bm.bmWidth = bm.bmHeight = 1;
bm.bmPlanes = bm.bmBitsPixel = 1;
bm.bmWidthBytes = 2;
bm.bmBits = NULL;
}
else
{
if (bm.bmHeight < 0)
bm.bmHeight = -bm.bmHeight;
if (bm.bmWidth < 0)
bm.bmWidth = -bm.bmWidth;
}
/* Create the BITMAPOBJ */
bmpobj = GDI_AllocObject( sizeof(BITMAPOBJ), BITMAP_MAGIC,
(HGDIOBJ *)&hbitmap, &bitmap_funcs );
if (!bmpobj)
{
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
return NULL;
}
TRACE("%dx%d, %d colors returning %p\n", bm.bmWidth, bm.bmHeight,
1 << (bm.bmPlanes * bm.bmBitsPixel), hbitmap);
bmpobj->size.cx = 0;
bmpobj->size.cy = 0;
bmpobj->bitmap = bm;
bmpobj->bitmap.bmBits = NULL;
bmpobj->funcs = NULL;
bmpobj->physBitmap = NULL;
bmpobj->dib = NULL;
bmpobj->segptr_bits = 0;
if (bm.bmBits)
SetBitmapBits( hbitmap, bm.bmHeight * bm.bmWidthBytes, bm.bmBits );
GDI_ReleaseObj( hbitmap );
return hbitmap;
}