Commit e896af40 authored by Alexandre Julliard's avatar Alexandre Julliard

gdi32: Always store a DIBSECTION structure in the bitmap object.

parent 8a9be0a3
...@@ -287,19 +287,15 @@ HBITMAP WINAPI CreateBitmapIndirect( const BITMAP *bmp ) ...@@ -287,19 +287,15 @@ HBITMAP WINAPI CreateBitmapIndirect( const BITMAP *bmp )
} }
/* Create the BITMAPOBJ */ /* Create the BITMAPOBJ */
if (!(bmpobj = HeapAlloc( GetProcessHeap(), 0, sizeof(*bmpobj) ))) if (!(bmpobj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*bmpobj) )))
{ {
SetLastError( ERROR_NOT_ENOUGH_MEMORY ); SetLastError( ERROR_NOT_ENOUGH_MEMORY );
return 0; return 0;
} }
bmpobj->size.cx = 0;
bmpobj->size.cy = 0;
bmpobj->bitmap = bm; bmpobj->bitmap = bm;
bmpobj->bitmap.bmBits = NULL; bmpobj->bitmap.bmBits = NULL;
bmpobj->funcs = &null_driver; bmpobj->funcs = &null_driver;
bmpobj->dib = NULL;
bmpobj->color_table = NULL;
if (!(hbitmap = alloc_gdi_handle( &bmpobj->header, OBJ_BITMAP, &bitmap_funcs ))) if (!(hbitmap = alloc_gdi_handle( &bmpobj->header, OBJ_BITMAP, &bitmap_funcs )))
{ {
......
...@@ -99,7 +99,7 @@ static BOOL copy_bitmap( struct brush_pattern *brush, HBITMAP bitmap ) ...@@ -99,7 +99,7 @@ static BOOL copy_bitmap( struct brush_pattern *brush, HBITMAP bitmap )
if (!bmp) return FALSE; if (!bmp) return FALSE;
if (!bmp->dib) if (!is_bitmapobj_dib( bmp ))
{ {
if ((brush->bitmap = CreateBitmap( bmp->bitmap.bmWidth, bmp->bitmap.bmHeight, if ((brush->bitmap = CreateBitmap( bmp->bitmap.bmWidth, bmp->bitmap.bmHeight,
bmp->bitmap.bmPlanes, bmp->bitmap.bmBitsPixel, NULL ))) bmp->bitmap.bmPlanes, bmp->bitmap.bmBitsPixel, NULL )))
...@@ -121,11 +121,11 @@ static BOOL copy_bitmap( struct brush_pattern *brush, HBITMAP bitmap ) ...@@ -121,11 +121,11 @@ static BOOL copy_bitmap( struct brush_pattern *brush, HBITMAP bitmap )
} }
info = HeapAlloc( GetProcessHeap(), 0, info = HeapAlloc( GetProcessHeap(), 0,
get_dib_info_size( (BITMAPINFO *)&bmp->dib->dsBmih, DIB_RGB_COLORS )); get_dib_info_size( (BITMAPINFO *)&bmp->dib.dsBmih, DIB_RGB_COLORS ));
if (!info) goto done; if (!info) goto done;
info->bmiHeader = bmp->dib->dsBmih; info->bmiHeader = bmp->dib.dsBmih;
if (info->bmiHeader.biCompression == BI_BITFIELDS) if (info->bmiHeader.biCompression == BI_BITFIELDS)
memcpy( &info->bmiHeader + 1, bmp->dib->dsBitfields, sizeof(bmp->dib->dsBitfields) ); memcpy( &info->bmiHeader + 1, bmp->dib.dsBitfields, sizeof(bmp->dib.dsBitfields) );
else if (info->bmiHeader.biClrUsed) else if (info->bmiHeader.biClrUsed)
memcpy( &info->bmiHeader + 1, bmp->color_table, info->bmiHeader.biClrUsed * sizeof(RGBQUAD) ); memcpy( &info->bmiHeader + 1, bmp->color_table, info->bmiHeader.biClrUsed * sizeof(RGBQUAD) );
if (!(brush->bits.ptr = HeapAlloc( GetProcessHeap(), 0, info->bmiHeader.biSizeImage ))) if (!(brush->bits.ptr = HeapAlloc( GetProcessHeap(), 0, info->bmiHeader.biSizeImage )))
...@@ -133,7 +133,7 @@ static BOOL copy_bitmap( struct brush_pattern *brush, HBITMAP bitmap ) ...@@ -133,7 +133,7 @@ static BOOL copy_bitmap( struct brush_pattern *brush, HBITMAP bitmap )
HeapFree( GetProcessHeap(), 0, info ); HeapFree( GetProcessHeap(), 0, info );
goto done; goto done;
} }
memcpy( brush->bits.ptr, bmp->dib->dsBm.bmBits, info->bmiHeader.biSizeImage ); memcpy( brush->bits.ptr, bmp->dib.dsBm.bmBits, info->bmiHeader.biSizeImage );
brush->bits.is_copy = TRUE; brush->bits.is_copy = TRUE;
brush->bits.free = free_heap_bits; brush->bits.free = free_heap_bits;
brush->info = info; brush->info = info;
......
...@@ -908,14 +908,10 @@ UINT WINAPI SetDIBColorTable( HDC hdc, UINT startpos, UINT entries, CONST RGBQUA ...@@ -908,14 +908,10 @@ UINT WINAPI SetDIBColorTable( HDC hdc, UINT startpos, UINT entries, CONST RGBQUA
if ((bitmap = GDI_GetObjPtr( dc->hBitmap, OBJ_BITMAP ))) if ((bitmap = GDI_GetObjPtr( dc->hBitmap, OBJ_BITMAP )))
{ {
/* Check if currently selected bitmap is a DIB */ if (startpos < bitmap->dib.dsBmih.biClrUsed)
if (bitmap->color_table)
{ {
if (startpos < bitmap->dib->dsBmih.biClrUsed) result = min( entries, bitmap->dib.dsBmih.biClrUsed - startpos );
{ memcpy(bitmap->color_table + startpos, colors, result * sizeof(RGBQUAD));
result = min( entries, bitmap->dib->dsBmih.biClrUsed - startpos );
memcpy(bitmap->color_table + startpos, colors, result * sizeof(RGBQUAD));
}
} }
GDI_ReleaseObj( dc->hBitmap ); GDI_ReleaseObj( dc->hBitmap );
...@@ -945,14 +941,10 @@ UINT WINAPI GetDIBColorTable( HDC hdc, UINT startpos, UINT entries, RGBQUAD *col ...@@ -945,14 +941,10 @@ UINT WINAPI GetDIBColorTable( HDC hdc, UINT startpos, UINT entries, RGBQUAD *col
if ((bitmap = GDI_GetObjPtr( dc->hBitmap, OBJ_BITMAP ))) if ((bitmap = GDI_GetObjPtr( dc->hBitmap, OBJ_BITMAP )))
{ {
/* Check if currently selected bitmap is a DIB */ if (startpos < bitmap->dib.dsBmih.biClrUsed)
if (bitmap->color_table)
{ {
if (startpos < bitmap->dib->dsBmih.biClrUsed) result = min( entries, bitmap->dib.dsBmih.biClrUsed - startpos );
{ memcpy(colors, bitmap->color_table + startpos, result * sizeof(RGBQUAD));
result = min( entries, bitmap->dib->dsBmih.biClrUsed - startpos );
memcpy(colors, bitmap->color_table + startpos, result * sizeof(RGBQUAD));
}
} }
GDI_ReleaseObj( dc->hBitmap ); GDI_ReleaseObj( dc->hBitmap );
} }
...@@ -1472,7 +1464,6 @@ HBITMAP WINAPI CreateDIBSection(HDC hdc, CONST BITMAPINFO *bmi, UINT usage, ...@@ -1472,7 +1464,6 @@ HBITMAP WINAPI CreateDIBSection(HDC hdc, CONST BITMAPINFO *bmi, UINT usage,
char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )]; char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )];
BITMAPINFO *info = (BITMAPINFO *)buffer; BITMAPINFO *info = (BITMAPINFO *)buffer;
HBITMAP ret = 0; HBITMAP ret = 0;
DIBSECTION *dib;
BITMAPOBJ *bmp; BITMAPOBJ *bmp;
void *mapBits = NULL; void *mapBits = NULL;
...@@ -1486,7 +1477,6 @@ HBITMAP WINAPI CreateDIBSection(HDC hdc, CONST BITMAPINFO *bmi, UINT usage, ...@@ -1486,7 +1477,6 @@ HBITMAP WINAPI CreateDIBSection(HDC hdc, CONST BITMAPINFO *bmi, UINT usage,
} }
if (!(bmp = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*bmp) ))) return 0; if (!(bmp = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*bmp) ))) return 0;
if (!(dib = HeapAlloc( GetProcessHeap(), 0, sizeof(*dib) ))) goto error;
TRACE("format (%d,%d), planes %d, bpp %d, %s, size %d %s\n", TRACE("format (%d,%d), planes %d, bpp %d, %s, size %d %s\n",
info->bmiHeader.biWidth, info->bmiHeader.biHeight, info->bmiHeader.biWidth, info->bmiHeader.biHeight,
...@@ -1494,45 +1484,44 @@ HBITMAP WINAPI CreateDIBSection(HDC hdc, CONST BITMAPINFO *bmi, UINT usage, ...@@ -1494,45 +1484,44 @@ HBITMAP WINAPI CreateDIBSection(HDC hdc, CONST BITMAPINFO *bmi, UINT usage,
info->bmiHeader.biCompression == BI_BITFIELDS? "BI_BITFIELDS" : "BI_RGB", info->bmiHeader.biCompression == BI_BITFIELDS? "BI_BITFIELDS" : "BI_RGB",
info->bmiHeader.biSizeImage, usage == DIB_PAL_COLORS? "PAL" : "RGB"); info->bmiHeader.biSizeImage, usage == DIB_PAL_COLORS? "PAL" : "RGB");
dib->dsBm.bmType = 0; bmp->dib.dsBm.bmType = 0;
dib->dsBm.bmWidth = info->bmiHeader.biWidth; bmp->dib.dsBm.bmWidth = info->bmiHeader.biWidth;
dib->dsBm.bmHeight = abs( info->bmiHeader.biHeight ); bmp->dib.dsBm.bmHeight = abs( info->bmiHeader.biHeight );
dib->dsBm.bmWidthBytes = get_dib_stride( info->bmiHeader.biWidth, info->bmiHeader.biBitCount ); bmp->dib.dsBm.bmWidthBytes = get_dib_stride( info->bmiHeader.biWidth, info->bmiHeader.biBitCount );
dib->dsBm.bmPlanes = info->bmiHeader.biPlanes; bmp->dib.dsBm.bmPlanes = info->bmiHeader.biPlanes;
dib->dsBm.bmBitsPixel = info->bmiHeader.biBitCount; bmp->dib.dsBm.bmBitsPixel = info->bmiHeader.biBitCount;
dib->dsBm.bmBits = NULL; bmp->dib.dsBmih = info->bmiHeader;
dib->dsBmih = info->bmiHeader;
bmp->funcs = &dib_driver; bmp->funcs = &dib_driver;
bmp->dib = dib;
if (info->bmiHeader.biBitCount <= 8) /* build the color table */ if (info->bmiHeader.biBitCount <= 8) /* build the color table */
{ {
if (usage == DIB_PAL_COLORS && !fill_color_table_from_pal_colors( info, hdc )) if (usage == DIB_PAL_COLORS && !fill_color_table_from_pal_colors( info, hdc ))
goto error; goto error;
dib->dsBmih.biClrUsed = info->bmiHeader.biClrUsed; bmp->dib.dsBmih.biClrUsed = info->bmiHeader.biClrUsed;
if (!(bmp->color_table = HeapAlloc( GetProcessHeap(), 0, dib->dsBmih.biClrUsed*sizeof(RGBQUAD) ))) if (!(bmp->color_table = HeapAlloc( GetProcessHeap(), 0,
bmp->dib.dsBmih.biClrUsed * sizeof(RGBQUAD) )))
goto error; goto error;
memcpy( bmp->color_table, info->bmiColors, dib->dsBmih.biClrUsed * sizeof(RGBQUAD) ); memcpy( bmp->color_table, info->bmiColors, bmp->dib.dsBmih.biClrUsed * sizeof(RGBQUAD) );
} }
/* set dsBitfields values */ /* set dsBitfields values */
if (info->bmiHeader.biBitCount == 16 && info->bmiHeader.biCompression == BI_RGB) if (info->bmiHeader.biBitCount == 16 && info->bmiHeader.biCompression == BI_RGB)
{ {
dib->dsBmih.biCompression = BI_BITFIELDS; bmp->dib.dsBmih.biCompression = BI_BITFIELDS;
dib->dsBitfields[0] = 0x7c00; bmp->dib.dsBitfields[0] = 0x7c00;
dib->dsBitfields[1] = 0x03e0; bmp->dib.dsBitfields[1] = 0x03e0;
dib->dsBitfields[2] = 0x001f; bmp->dib.dsBitfields[2] = 0x001f;
} }
else if (info->bmiHeader.biCompression == BI_BITFIELDS) else if (info->bmiHeader.biCompression == BI_BITFIELDS)
{ {
if (usage == DIB_PAL_COLORS) goto error; if (usage == DIB_PAL_COLORS) goto error;
dib->dsBitfields[0] = *(const DWORD *)info->bmiColors; bmp->dib.dsBitfields[0] = *(const DWORD *)info->bmiColors;
dib->dsBitfields[1] = *((const DWORD *)info->bmiColors + 1); bmp->dib.dsBitfields[1] = *((const DWORD *)info->bmiColors + 1);
dib->dsBitfields[2] = *((const DWORD *)info->bmiColors + 2); bmp->dib.dsBitfields[2] = *((const DWORD *)info->bmiColors + 2);
if (!dib->dsBitfields[0] || !dib->dsBitfields[1] || !dib->dsBitfields[2]) goto error; if (!bmp->dib.dsBitfields[0] || !bmp->dib.dsBitfields[1] || !bmp->dib.dsBitfields[2]) goto error;
} }
else dib->dsBitfields[0] = dib->dsBitfields[1] = dib->dsBitfields[2] = 0; else bmp->dib.dsBitfields[0] = bmp->dib.dsBitfields[1] = bmp->dib.dsBitfields[2] = 0;
/* get storage location for DIB bits */ /* get storage location for DIB bits */
...@@ -1544,35 +1533,34 @@ HBITMAP WINAPI CreateDIBSection(HDC hdc, CONST BITMAPINFO *bmi, UINT usage, ...@@ -1544,35 +1533,34 @@ HBITMAP WINAPI CreateDIBSection(HDC hdc, CONST BITMAPINFO *bmi, UINT usage,
GetSystemInfo( &SystemInfo ); GetSystemInfo( &SystemInfo );
mapOffset = offset - (offset % SystemInfo.dwAllocationGranularity); mapOffset = offset - (offset % SystemInfo.dwAllocationGranularity);
mapSize = dib->dsBmih.biSizeImage + (offset - mapOffset); mapSize = bmp->dib.dsBmih.biSizeImage + (offset - mapOffset);
mapBits = MapViewOfFile( section, FILE_MAP_ALL_ACCESS, 0, mapOffset, mapSize ); mapBits = MapViewOfFile( section, FILE_MAP_ALL_ACCESS, 0, mapOffset, mapSize );
if (mapBits) dib->dsBm.bmBits = (char *)mapBits + (offset - mapOffset); if (mapBits) bmp->dib.dsBm.bmBits = (char *)mapBits + (offset - mapOffset);
} }
else else
{ {
offset = 0; offset = 0;
dib->dsBm.bmBits = VirtualAlloc( NULL, dib->dsBmih.biSizeImage, bmp->dib.dsBm.bmBits = VirtualAlloc( NULL, bmp->dib.dsBmih.biSizeImage,
MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE ); MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE );
} }
dib->dshSection = section; bmp->dib.dshSection = section;
dib->dsOffset = offset; bmp->dib.dsOffset = offset;
if (!dib->dsBm.bmBits) goto error; if (!bmp->dib.dsBm.bmBits) goto error;
bmp->bitmap = dib->dsBm; bmp->bitmap = bmp->dib.dsBm;
bmp->bitmap.bmWidthBytes = get_bitmap_stride( info->bmiHeader.biWidth, info->bmiHeader.biBitCount ); bmp->bitmap.bmWidthBytes = get_bitmap_stride( info->bmiHeader.biWidth, info->bmiHeader.biBitCount );
bmp->bitmap.bmBits = NULL; bmp->bitmap.bmBits = NULL;
if (!(ret = alloc_gdi_handle( &bmp->header, OBJ_BITMAP, &dib_funcs ))) goto error; if (!(ret = alloc_gdi_handle( &bmp->header, OBJ_BITMAP, &dib_funcs ))) goto error;
if (bits) *bits = dib->dsBm.bmBits; if (bits) *bits = bmp->dib.dsBm.bmBits;
return ret; return ret;
error: error:
if (section) UnmapViewOfFile( mapBits ); if (section) UnmapViewOfFile( mapBits );
else VirtualFree( dib->dsBm.bmBits, 0, MEM_RELEASE ); else VirtualFree( bmp->dib.dsBm.bmBits, 0, MEM_RELEASE );
HeapFree( GetProcessHeap(), 0, bmp->color_table ); HeapFree( GetProcessHeap(), 0, bmp->color_table );
HeapFree( GetProcessHeap(), 0, dib );
HeapFree( GetProcessHeap(), 0, bmp ); HeapFree( GetProcessHeap(), 0, bmp );
return 0; return 0;
} }
...@@ -1670,14 +1658,14 @@ static INT DIB_GetObject( HGDIOBJ handle, INT count, LPVOID buffer ) ...@@ -1670,14 +1658,14 @@ static INT DIB_GetObject( HGDIOBJ handle, INT count, LPVOID buffer )
else if (count >= sizeof(DIBSECTION)) else if (count >= sizeof(DIBSECTION))
{ {
DIBSECTION *dib = buffer; DIBSECTION *dib = buffer;
*dib = *bmp->dib; *dib = bmp->dib;
dib->dsBmih.biHeight = abs( dib->dsBmih.biHeight ); dib->dsBmih.biHeight = abs( dib->dsBmih.biHeight );
ret = sizeof(DIBSECTION); ret = sizeof(DIBSECTION);
} }
else if (count >= sizeof(BITMAP)) else if (count >= sizeof(BITMAP))
{ {
BITMAP *bitmap = buffer; BITMAP *bitmap = buffer;
*bitmap = bmp->dib->dsBm; *bitmap = bmp->dib.dsBm;
ret = sizeof(BITMAP); ret = sizeof(BITMAP);
} }
...@@ -1695,16 +1683,15 @@ static BOOL DIB_DeleteObject( HGDIOBJ handle ) ...@@ -1695,16 +1683,15 @@ static BOOL DIB_DeleteObject( HGDIOBJ handle )
if (!(bmp = free_gdi_handle( handle ))) return FALSE; if (!(bmp = free_gdi_handle( handle ))) return FALSE;
if (bmp->dib->dshSection) if (bmp->dib.dshSection)
{ {
SYSTEM_INFO SystemInfo; SYSTEM_INFO SystemInfo;
GetSystemInfo( &SystemInfo ); GetSystemInfo( &SystemInfo );
UnmapViewOfFile( (char *)bmp->dib->dsBm.bmBits - UnmapViewOfFile( (char *)bmp->dib.dsBm.bmBits -
(bmp->dib->dsOffset % SystemInfo.dwAllocationGranularity) ); (bmp->dib.dsOffset % SystemInfo.dwAllocationGranularity) );
} }
else VirtualFree( bmp->dib->dsBm.bmBits, 0, MEM_RELEASE ); else VirtualFree( bmp->dib.dsBm.bmBits, 0, MEM_RELEASE );
HeapFree(GetProcessHeap(), 0, bmp->dib);
HeapFree(GetProcessHeap(), 0, bmp->color_table); HeapFree(GetProcessHeap(), 0, bmp->color_table);
return HeapFree( GetProcessHeap(), 0, bmp ); return HeapFree( GetProcessHeap(), 0, bmp );
} }
...@@ -160,7 +160,7 @@ void init_dib_info_from_bitmapinfo(dib_info *dib, const BITMAPINFO *info, void * ...@@ -160,7 +160,7 @@ void init_dib_info_from_bitmapinfo(dib_info *dib, const BITMAPINFO *info, void *
BOOL init_dib_info_from_bitmapobj(dib_info *dib, BITMAPOBJ *bmp, enum dib_info_flags flags) BOOL init_dib_info_from_bitmapobj(dib_info *dib, BITMAPOBJ *bmp, enum dib_info_flags flags)
{ {
if (!bmp->dib) if (!is_bitmapobj_dib( bmp ))
{ {
BITMAPINFO info; BITMAPINFO info;
...@@ -174,8 +174,8 @@ BOOL init_dib_info_from_bitmapobj(dib_info *dib, BITMAPOBJ *bmp, enum dib_info_f ...@@ -174,8 +174,8 @@ BOOL init_dib_info_from_bitmapobj(dib_info *dib, BITMAPOBJ *bmp, enum dib_info_f
} }
init_dib_info_from_bitmapinfo( dib, &info, bmp->bitmap.bmBits, flags ); init_dib_info_from_bitmapinfo( dib, &info, bmp->bitmap.bmBits, flags );
} }
else init_dib_info( dib, &bmp->dib->dsBmih, bmp->dib->dsBitfields, else init_dib_info( dib, &bmp->dib.dsBmih, bmp->dib.dsBitfields,
bmp->color_table, bmp->dib->dsBm.bmBits, flags ); bmp->color_table, bmp->dib.dsBm.bmBits, flags );
return TRUE; return TRUE;
} }
......
...@@ -175,13 +175,17 @@ typedef struct tagBITMAPOBJ ...@@ -175,13 +175,17 @@ typedef struct tagBITMAPOBJ
{ {
GDIOBJHDR header; GDIOBJHDR header;
BITMAP bitmap; BITMAP bitmap;
DIBSECTION dib;
SIZE size; /* For SetBitmapDimension() */ SIZE size; /* For SetBitmapDimension() */
const struct gdi_dc_funcs *funcs; /* DC function table */
/* For device-independent bitmaps: */
DIBSECTION *dib;
RGBQUAD *color_table; /* DIB color table if <= 8bpp (always 1 << bpp in size) */ RGBQUAD *color_table; /* DIB color table if <= 8bpp (always 1 << bpp in size) */
const struct gdi_dc_funcs *funcs; /* DC function table */
} BITMAPOBJ; } BITMAPOBJ;
static inline BOOL is_bitmapobj_dib( const BITMAPOBJ *bmp )
{
return bmp->dib.dsBmih.biSize != 0;
}
/* bidi.c */ /* bidi.c */
/* Wine_GCPW Flags */ /* Wine_GCPW Flags */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment