gdi32: Export a bitmap conversion function.
This commit is contained in:
parent
dfaee0f3b1
commit
09a1418449
|
@ -200,6 +200,20 @@ BOOL init_dib_info_from_packed(dib_info *dib, const BITMAPINFOHEADER *bi, WORD u
|
||||||
return init_dib_info(dib, bi, masks, color_table, num_colors, ptr, private_color_table);
|
return init_dib_info(dib, bi, masks, color_table, num_colors, ptr, private_color_table);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOL init_dib_info_from_bitmapinfo(dib_info *dib, const BITMAPINFO *info, void *bits, enum dib_info_flags flags)
|
||||||
|
{
|
||||||
|
unsigned int colors = 0;
|
||||||
|
void *colorptr = (char *)&info->bmiHeader + info->bmiHeader.biSize;
|
||||||
|
const DWORD *bitfields = (info->bmiHeader.biCompression == BI_BITFIELDS) ? (DWORD *)colorptr : NULL;
|
||||||
|
|
||||||
|
if (info->bmiHeader.biBitCount <= 8)
|
||||||
|
{
|
||||||
|
colors = 1 << info->bmiHeader.biBitCount;
|
||||||
|
if (info->bmiHeader.biClrUsed) colors = info->bmiHeader.biClrUsed;
|
||||||
|
}
|
||||||
|
return init_dib_info( dib, &info->bmiHeader, bitfields, colors ? colorptr : NULL, colors, bits, flags );
|
||||||
|
}
|
||||||
|
|
||||||
static void clear_dib_info(dib_info *dib)
|
static void clear_dib_info(dib_info *dib)
|
||||||
{
|
{
|
||||||
dib->color_table = NULL;
|
dib->color_table = NULL;
|
||||||
|
@ -252,32 +266,23 @@ void copy_dib_color_info(dib_info *dst, const dib_info *src)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************************
|
DWORD convert_bitmapinfo( const BITMAPINFO *src_info, void *src_bits, const RECT *src_rect,
|
||||||
* convert_dib
|
const BITMAPINFO *dst_info, void *dst_bits )
|
||||||
*
|
|
||||||
* Converts src into the format specified in dst.
|
|
||||||
*
|
|
||||||
* FIXME: At the moment this always creates a top-down dib,
|
|
||||||
* do we want to give the option of bottom-up?
|
|
||||||
*/
|
|
||||||
BOOL convert_dib(dib_info *dst, const dib_info *src)
|
|
||||||
{
|
{
|
||||||
BOOL ret;
|
dib_info src_dib, dst_dib;
|
||||||
RECT src_rect;
|
DWORD ret;
|
||||||
|
|
||||||
dst->height = src->height;
|
if ( !init_dib_info_from_bitmapinfo( &src_dib, src_info, src_bits, 0 ) )
|
||||||
dst->width = src->width;
|
return ERROR_BAD_FORMAT;
|
||||||
dst->stride = ((dst->width * dst->bit_count + 31) >> 3) & ~3;
|
if ( !init_dib_info_from_bitmapinfo( &dst_dib, dst_info, dst_bits, 0 ) )
|
||||||
dst->ptr_to_free = dst->bits = HeapAlloc(GetProcessHeap(), 0, dst->height * dst->stride);
|
return ERROR_BAD_FORMAT;
|
||||||
|
|
||||||
src_rect.left = src_rect.top = 0;
|
ret = dst_dib.funcs->convert_to( &dst_dib, &src_dib, src_rect );
|
||||||
src_rect.right = src->width;
|
|
||||||
src_rect.bottom = src->height;
|
|
||||||
|
|
||||||
ret = dst->funcs->convert_to(dst, src, &src_rect);
|
/* We shared the color tables, so there's no need to free the dib_infos here */
|
||||||
|
|
||||||
if(!ret) free_dib_info(dst);
|
if(!ret) return ERROR_BAD_FORMAT;
|
||||||
return ret;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void update_fg_colors( dibdrv_physdev *pdev )
|
static void update_fg_colors( dibdrv_physdev *pdev )
|
||||||
|
|
|
@ -1285,16 +1285,30 @@ HBRUSH dibdrv_SelectBrush( PHYSDEV dev, HBRUSH hbrush )
|
||||||
dib_info orig_dib;
|
dib_info orig_dib;
|
||||||
WORD usage = LOWORD(logbrush.lbColor);
|
WORD usage = LOWORD(logbrush.lbColor);
|
||||||
HPALETTE pal = (usage == DIB_PAL_COLORS) ? GetCurrentObject(dev->hdc, OBJ_PAL) : NULL;
|
HPALETTE pal = (usage == DIB_PAL_COLORS) ? GetCurrentObject(dev->hdc, OBJ_PAL) : NULL;
|
||||||
|
RECT rect;
|
||||||
|
|
||||||
if(!bi) return NULL;
|
if(!bi) return NULL;
|
||||||
if(init_dib_info_from_packed(&orig_dib, bi, usage, pal))
|
if(init_dib_info_from_packed(&orig_dib, bi, usage, pal))
|
||||||
{
|
{
|
||||||
copy_dib_color_info(&pdev->brush_dib, &pdev->dib);
|
copy_dib_color_info(&pdev->brush_dib, &pdev->dib);
|
||||||
if(convert_dib(&pdev->brush_dib, &orig_dib))
|
|
||||||
|
pdev->brush_dib.height = orig_dib.height;
|
||||||
|
pdev->brush_dib.width = orig_dib.width;
|
||||||
|
pdev->brush_dib.stride = ((pdev->brush_dib.width * pdev->brush_dib.bit_count + 31) >> 3) & ~3;
|
||||||
|
pdev->brush_dib.ptr_to_free = HeapAlloc( GetProcessHeap(), 0, pdev->brush_dib.height * pdev->brush_dib.stride );
|
||||||
|
pdev->brush_dib.bits = pdev->brush_dib.ptr_to_free;
|
||||||
|
|
||||||
|
rect.left = rect.top = 0;
|
||||||
|
rect.right = orig_dib.width;
|
||||||
|
rect.bottom = orig_dib.height;
|
||||||
|
|
||||||
|
if(pdev->brush_dib.funcs->convert_to(&pdev->brush_dib, &orig_dib, &rect))
|
||||||
{
|
{
|
||||||
pdev->brush_rects = pattern_brush;
|
pdev->brush_rects = pattern_brush;
|
||||||
pdev->defer &= ~DEFER_BRUSH;
|
pdev->defer &= ~DEFER_BRUSH;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
free_dib_info(&pdev->brush_dib);
|
||||||
free_dib_info(&orig_dib);
|
free_dib_info(&orig_dib);
|
||||||
}
|
}
|
||||||
GlobalUnlock((HGLOBAL)logbrush.lbHatch);
|
GlobalUnlock((HGLOBAL)logbrush.lbHatch);
|
||||||
|
|
|
@ -338,6 +338,9 @@ extern int DIB_GetDIBImageBytes( int width, int height, int depth ) DECLSPEC_HID
|
||||||
extern int bitmap_info_size( const BITMAPINFO * info, WORD coloruse ) DECLSPEC_HIDDEN;
|
extern int bitmap_info_size( const BITMAPINFO * info, WORD coloruse ) DECLSPEC_HIDDEN;
|
||||||
extern int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, LONG *width,
|
extern int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, LONG *width,
|
||||||
LONG *height, WORD *planes, WORD *bpp, DWORD *compr, DWORD *size ) DECLSPEC_HIDDEN;
|
LONG *height, WORD *planes, WORD *bpp, DWORD *compr, DWORD *size ) DECLSPEC_HIDDEN;
|
||||||
|
extern DWORD convert_bitmapinfo( const BITMAPINFO *src_info, void *src_bits, const RECT *src_rect,
|
||||||
|
const BITMAPINFO *dst_info, void *dst_bits ) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
|
|
||||||
/* driver.c */
|
/* driver.c */
|
||||||
extern const DC_FUNCTIONS null_driver DECLSPEC_HIDDEN;
|
extern const DC_FUNCTIONS null_driver DECLSPEC_HIDDEN;
|
||||||
|
|
Loading…
Reference in New Issue