Commit eb87e694 authored by Alexandre Julliard's avatar Alexandre Julliard

gdi32: Add inline helpers to compute DIB stride and total size.

parent 1f8a0eb4
...@@ -62,9 +62,7 @@ static HGLOBAL dib_copy(const BITMAPINFO *info, UINT coloruse) ...@@ -62,9 +62,7 @@ static HGLOBAL dib_copy(const BITMAPINFO *info, UINT coloruse)
if (info->bmiHeader.biCompression != BI_RGB && info->bmiHeader.biCompression != BI_BITFIELDS) if (info->bmiHeader.biCompression != BI_RGB && info->bmiHeader.biCompression != BI_BITFIELDS)
size = info->bmiHeader.biSizeImage; size = info->bmiHeader.biSizeImage;
else else
size = DIB_GetDIBImageBytes(info->bmiHeader.biWidth, size = get_dib_image_size(info);
info->bmiHeader.biHeight,
info->bmiHeader.biBitCount);
size += bitmap_info_size( info, coloruse ); size += bitmap_info_size( info, coloruse );
if (!(hmem = GlobalAlloc( GMEM_MOVEABLE, size ))) if (!(hmem = GlobalAlloc( GMEM_MOVEABLE, size )))
......
...@@ -72,48 +72,6 @@ ...@@ -72,48 +72,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(bitmap); WINE_DEFAULT_DEBUG_CHANNEL(bitmap);
/*
Some of the following helper functions are duplicated in
dlls/x11drv/dib.c
*/
/***********************************************************************
* DIB_GetDIBWidthBytes
*
* Return the width of a DIB bitmap in bytes. DIB bitmap data is 32-bit aligned.
*/
int DIB_GetDIBWidthBytes( int width, int depth )
{
int words;
switch(depth)
{
case 1: words = (width + 31) / 32; break;
case 4: words = (width + 7) / 8; break;
case 8: words = (width + 3) / 4; break;
case 15:
case 16: words = (width + 1) / 2; break;
case 24: words = (width * 3 + 3)/4; break;
default:
WARN("(%d): Unsupported depth\n", depth );
/* fall through */
case 32:
words = width;
}
return 4 * words;
}
/***********************************************************************
* DIB_GetDIBImageBytes
*
* Return the number of bytes used to hold the image in a DIB bitmap.
*/
int DIB_GetDIBImageBytes( int width, int height, int depth )
{
return DIB_GetDIBWidthBytes( width, depth ) * abs( height );
}
/*********************************************************************** /***********************************************************************
* bitmap_info_size * bitmap_info_size
...@@ -472,9 +430,7 @@ static int fill_query_info( BITMAPINFO *info, BITMAPOBJ *bmp ) ...@@ -472,9 +430,7 @@ static int fill_query_info( BITMAPINFO *info, BITMAPOBJ *bmp )
header.biBitCount = bmp->bitmap.bmBitsPixel; header.biBitCount = bmp->bitmap.bmBitsPixel;
} }
header.biSizeImage = DIB_GetDIBImageBytes( bmp->bitmap.bmWidth, header.biSizeImage = get_dib_image_size( (BITMAPINFO *)&header );
bmp->bitmap.bmHeight,
bmp->bitmap.bmBitsPixel );
header.biXPelsPerMeter = 0; header.biXPelsPerMeter = 0;
header.biYPelsPerMeter = 0; header.biYPelsPerMeter = 0;
header.biClrUsed = 0; header.biClrUsed = 0;
...@@ -652,7 +608,7 @@ INT WINAPI GetDIBits( ...@@ -652,7 +608,7 @@ INT WINAPI GetDIBits(
dst_info->bmiHeader.biPlanes = planes; dst_info->bmiHeader.biPlanes = planes;
dst_info->bmiHeader.biBitCount = bpp; dst_info->bmiHeader.biBitCount = bpp;
dst_info->bmiHeader.biCompression = compr; dst_info->bmiHeader.biCompression = compr;
dst_info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes( width, height, bpp ); dst_info->bmiHeader.biSizeImage = get_dib_image_size( dst_info );
dst_info->bmiHeader.biXPelsPerMeter = 0; dst_info->bmiHeader.biXPelsPerMeter = 0;
dst_info->bmiHeader.biYPelsPerMeter = 0; dst_info->bmiHeader.biYPelsPerMeter = 0;
dst_info->bmiHeader.biClrUsed = 0; dst_info->bmiHeader.biClrUsed = 0;
...@@ -971,7 +927,7 @@ HBITMAP WINAPI CreateDIBSection(HDC hdc, CONST BITMAPINFO *bmi, UINT usage, ...@@ -971,7 +927,7 @@ HBITMAP WINAPI CreateDIBSection(HDC hdc, CONST BITMAPINFO *bmi, UINT usage,
dib->dsBm.bmType = 0; dib->dsBm.bmType = 0;
dib->dsBm.bmWidth = width; dib->dsBm.bmWidth = width;
dib->dsBm.bmHeight = height >= 0 ? height : -height; dib->dsBm.bmHeight = height >= 0 ? height : -height;
dib->dsBm.bmWidthBytes = DIB_GetDIBWidthBytes(width, bpp); dib->dsBm.bmWidthBytes = get_dib_stride( width, bpp );
dib->dsBm.bmPlanes = planes; dib->dsBm.bmPlanes = planes;
dib->dsBm.bmBitsPixel = bpp; dib->dsBm.bmBitsPixel = bpp;
dib->dsBm.bmBits = NULL; dib->dsBm.bmBits = NULL;
......
...@@ -72,7 +72,7 @@ static BOOL init_dib_info(dib_info *dib, const BITMAPINFOHEADER *bi, const DWORD ...@@ -72,7 +72,7 @@ static BOOL init_dib_info(dib_info *dib, const BITMAPINFOHEADER *bi, const DWORD
dib->bit_count = bi->biBitCount; dib->bit_count = bi->biBitCount;
dib->width = bi->biWidth; dib->width = bi->biWidth;
dib->height = bi->biHeight; dib->height = bi->biHeight;
dib->stride = ((dib->width * dib->bit_count + 31) >> 3) & ~3; dib->stride = get_dib_stride( dib->width, dib->bit_count );
dib->bits = bits; dib->bits = bits;
dib->ptr_to_free = NULL; dib->ptr_to_free = NULL;
dib->flags = flags; dib->flags = flags;
......
...@@ -1133,7 +1133,7 @@ static BOOL create_hatch_brush_bits(dibdrv_physdev *pdev) ...@@ -1133,7 +1133,7 @@ static BOOL create_hatch_brush_bits(dibdrv_physdev *pdev)
copy_dib_color_info(&pdev->brush_dib, &pdev->dib); copy_dib_color_info(&pdev->brush_dib, &pdev->dib);
pdev->brush_dib.width = 8; pdev->brush_dib.width = 8;
pdev->brush_dib.height = 8; pdev->brush_dib.height = 8;
pdev->brush_dib.stride = ((pdev->brush_dib.width * pdev->brush_dib.bit_count + 31) >> 3) & ~3; pdev->brush_dib.stride = get_dib_stride( pdev->brush_dib.width, pdev->brush_dib.bit_count );
size = pdev->brush_dib.height * pdev->brush_dib.stride; size = pdev->brush_dib.height * pdev->brush_dib.stride;
...@@ -1294,7 +1294,7 @@ HBRUSH dibdrv_SelectBrush( PHYSDEV dev, HBRUSH hbrush ) ...@@ -1294,7 +1294,7 @@ HBRUSH dibdrv_SelectBrush( PHYSDEV dev, HBRUSH hbrush )
pdev->brush_dib.height = orig_dib.height; pdev->brush_dib.height = orig_dib.height;
pdev->brush_dib.width = orig_dib.width; 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.stride = get_dib_stride( pdev->brush_dib.width, pdev->brush_dib.bit_count );
pdev->brush_dib.ptr_to_free = HeapAlloc( GetProcessHeap(), 0, pdev->brush_dib.height * pdev->brush_dib.stride ); 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; pdev->brush_dib.bits = pdev->brush_dib.ptr_to_free;
......
...@@ -99,7 +99,7 @@ BOOL EMFDRV_StretchBlt( PHYSDEV devDst, struct bitblt_coords *dst, ...@@ -99,7 +99,7 @@ BOOL EMFDRV_StretchBlt( PHYSDEV devDst, struct bitblt_coords *dst,
nBPP = BM.bmPlanes * BM.bmBitsPixel; nBPP = BM.bmPlanes * BM.bmBitsPixel;
if(nBPP > 8) nBPP = 24; /* FIXME Can't get 16bpp to work for some reason */ if(nBPP > 8) nBPP = 24; /* FIXME Can't get 16bpp to work for some reason */
bitsSize = DIB_GetDIBWidthBytes(BM.bmWidth, nBPP) * BM.bmHeight; bitsSize = get_dib_stride( BM.bmWidth, nBPP ) * BM.bmHeight;
bmiSize = sizeof(BITMAPINFOHEADER) + bmiSize = sizeof(BITMAPINFOHEADER) +
(nBPP <= 8 ? 1 << nBPP : 0) * sizeof(RGBQUAD); (nBPP <= 8 ? 1 << nBPP : 0) * sizeof(RGBQUAD);
...@@ -175,11 +175,8 @@ INT EMFDRV_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst, INT hei ...@@ -175,11 +175,8 @@ INT EMFDRV_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst, INT hei
{ {
EMRSTRETCHDIBITS *emr; EMRSTRETCHDIBITS *emr;
BOOL ret; BOOL ret;
UINT bmi_size=0, bits_size, emr_size; UINT bmi_size=0, emr_size;
UINT bits_size = get_dib_image_size(info);
bits_size = DIB_GetDIBImageBytes(info->bmiHeader.biWidth,
info->bmiHeader.biHeight,
info->bmiHeader.biBitCount);
/* calculate the size of the colour table */ /* calculate the size of the colour table */
bmi_size = bitmap_info_size(info, wUsage); bmi_size = bitmap_info_size(info, wUsage);
...@@ -235,13 +232,9 @@ INT EMFDRV_SetDIBitsToDevice( PHYSDEV dev, INT xDst, INT yDst, DWORD width, DWOR ...@@ -235,13 +232,9 @@ INT EMFDRV_SetDIBitsToDevice( PHYSDEV dev, INT xDst, INT yDst, DWORD width, DWOR
LPCVOID bits, const BITMAPINFO *info, UINT wUsage ) LPCVOID bits, const BITMAPINFO *info, UINT wUsage )
{ {
EMRSETDIBITSTODEVICE* pEMR; EMRSETDIBITSTODEVICE* pEMR;
DWORD size, bmiSize, bitsSize; DWORD bmiSize = bitmap_info_size(info, wUsage);
DWORD bitsSize = get_dib_image_size( info );
bmiSize = bitmap_info_size(info, wUsage); DWORD size = sizeof(EMRSETDIBITSTODEVICE) + bmiSize + bitsSize;
bitsSize = DIB_GetDIBImageBytes( info->bmiHeader.biWidth,
info->bmiHeader.biHeight,
info->bmiHeader.biBitCount );
size = sizeof(EMRSETDIBITSTODEVICE) + bmiSize + bitsSize;
pEMR = HeapAlloc(GetProcessHeap(), 0, size); pEMR = HeapAlloc(GetProcessHeap(), 0, size);
if (!pEMR) return 0; if (!pEMR) return 0;
......
...@@ -171,9 +171,7 @@ DWORD EMFDRV_CreateBrushIndirect( PHYSDEV dev, HBRUSH hBrush ) ...@@ -171,9 +171,7 @@ DWORD EMFDRV_CreateBrushIndirect( PHYSDEV dev, HBRUSH hBrush )
if (info->bmiHeader.biCompression) if (info->bmiHeader.biCompression)
bmSize = info->bmiHeader.biSizeImage; bmSize = info->bmiHeader.biSizeImage;
else else
bmSize = DIB_GetDIBImageBytes(info->bmiHeader.biWidth, bmSize = get_dib_image_size( info );
info->bmiHeader.biHeight,
info->bmiHeader.biBitCount);
biSize = bitmap_info_size(info, LOWORD(logbrush.lbColor)); biSize = bitmap_info_size(info, LOWORD(logbrush.lbColor));
size = sizeof(EMRCREATEDIBPATTERNBRUSHPT) + biSize + bmSize; size = sizeof(EMRCREATEDIBPATTERNBRUSHPT) + biSize + bmSize;
emr = HeapAlloc( GetProcessHeap(), 0, size ); emr = HeapAlloc( GetProcessHeap(), 0, size );
...@@ -212,7 +210,7 @@ DWORD EMFDRV_CreateBrushIndirect( PHYSDEV dev, HBRUSH hBrush ) ...@@ -212,7 +210,7 @@ DWORD EMFDRV_CreateBrushIndirect( PHYSDEV dev, HBRUSH hBrush )
} }
/* BMP will be aligned to 32 bits, not 16 */ /* BMP will be aligned to 32 bits, not 16 */
bmSize = DIB_GetDIBImageBytes(bm.bmWidth, bm.bmHeight, bm.bmBitsPixel); bmSize = get_dib_stride(bm.bmWidth, bm.bmBitsPixel) * bm.bmHeight;
biSize = sizeof(BITMAPINFOHEADER); biSize = sizeof(BITMAPINFOHEADER);
/* FIXME: There is an extra DWORD written by native before the BMI. /* FIXME: There is an extra DWORD written by native before the BMI.
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#define __WINE_GDI_PRIVATE_H #define __WINE_GDI_PRIVATE_H
#include <math.h> #include <math.h>
#include <stdlib.h>
#include <stdarg.h> #include <stdarg.h>
#include "windef.h" #include "windef.h"
#include "winbase.h" #include "winbase.h"
...@@ -336,8 +337,6 @@ extern void DC_InitDC( DC * dc ) DECLSPEC_HIDDEN; ...@@ -336,8 +337,6 @@ extern void DC_InitDC( DC * dc ) DECLSPEC_HIDDEN;
extern void DC_UpdateXforms( DC * dc ) DECLSPEC_HIDDEN; extern void DC_UpdateXforms( DC * dc ) DECLSPEC_HIDDEN;
/* dib.c */ /* dib.c */
extern int DIB_GetDIBWidthBytes( int width, int depth ) DECLSPEC_HIDDEN;
extern int DIB_GetDIBImageBytes( int width, int height, int depth ) DECLSPEC_HIDDEN;
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;
...@@ -545,4 +544,15 @@ static inline void offset_rect( RECT *rect, int offset_x, int offset_y ) ...@@ -545,4 +544,15 @@ static inline void offset_rect( RECT *rect, int offset_x, int offset_y )
rect->bottom += offset_y; rect->bottom += offset_y;
} }
static inline int get_dib_stride( int width, int bpp )
{
return ((width * bpp + 31) >> 3) & ~3;
}
static inline int get_dib_image_size( const BITMAPINFO *info )
{
return get_dib_stride( info->bmiHeader.biWidth, info->bmiHeader.biBitCount )
* abs( info->bmiHeader.biHeight );
}
#endif /* __WINE_GDI_PRIVATE_H */ #endif /* __WINE_GDI_PRIVATE_H */
...@@ -69,7 +69,7 @@ BOOL MFDRV_StretchBlt( PHYSDEV devDst, struct bitblt_coords *dst, ...@@ -69,7 +69,7 @@ BOOL MFDRV_StretchBlt( PHYSDEV devDst, struct bitblt_coords *dst,
if(nBPP > 8) nBPP = 24; /* FIXME Can't get 16bpp to work for some reason */ if(nBPP > 8) nBPP = 24; /* FIXME Can't get 16bpp to work for some reason */
len = sizeof(METARECORD) + 10 * sizeof(INT16) len = sizeof(METARECORD) + 10 * sizeof(INT16)
+ sizeof(BITMAPINFOHEADER) + (nBPP <= 8 ? 1 << nBPP: 0) * sizeof(RGBQUAD) + sizeof(BITMAPINFOHEADER) + (nBPP <= 8 ? 1 << nBPP: 0) * sizeof(RGBQUAD)
+ DIB_GetDIBWidthBytes(BM.bmWidth, nBPP) * BM.bmHeight; + get_dib_stride( BM.bmWidth, nBPP ) * BM.bmHeight;
if (!(mr = HeapAlloc( GetProcessHeap(), 0, len))) if (!(mr = HeapAlloc( GetProcessHeap(), 0, len)))
return FALSE; return FALSE;
mr->rdFunction = META_DIBSTRETCHBLT; mr->rdFunction = META_DIBSTRETCHBLT;
...@@ -79,7 +79,7 @@ BOOL MFDRV_StretchBlt( PHYSDEV devDst, struct bitblt_coords *dst, ...@@ -79,7 +79,7 @@ BOOL MFDRV_StretchBlt( PHYSDEV devDst, struct bitblt_coords *dst,
lpBMI->biHeight = BM.bmHeight; lpBMI->biHeight = BM.bmHeight;
lpBMI->biPlanes = 1; lpBMI->biPlanes = 1;
lpBMI->biBitCount = nBPP; lpBMI->biBitCount = nBPP;
lpBMI->biSizeImage = DIB_GetDIBWidthBytes(BM.bmWidth, nBPP) * lpBMI->biHeight; lpBMI->biSizeImage = get_dib_image_size( (BITMAPINFO *)lpBMI );
lpBMI->biClrUsed = nBPP <= 8 ? 1 << nBPP : 0; lpBMI->biClrUsed = nBPP <= 8 ? 1 << nBPP : 0;
lpBMI->biCompression = BI_RGB; lpBMI->biCompression = BI_RGB;
lpBMI->biXPelsPerMeter = MulDiv(GetDeviceCaps(devSrc->hdc,LOGPIXELSX),3937,100); lpBMI->biXPelsPerMeter = MulDiv(GetDeviceCaps(devSrc->hdc,LOGPIXELSX),3937,100);
...@@ -135,16 +135,10 @@ INT MFDRV_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst, ...@@ -135,16 +135,10 @@ INT MFDRV_StretchDIBits( PHYSDEV dev, INT xDst, INT yDst, INT widthDst,
INT heightSrc, const void *bits, INT heightSrc, const void *bits,
const BITMAPINFO *info, UINT wUsage, DWORD dwRop ) const BITMAPINFO *info, UINT wUsage, DWORD dwRop )
{ {
DWORD len, infosize, imagesize; DWORD infosize = bitmap_info_size(info, wUsage);
METARECORD *mr; DWORD imagesize = get_dib_image_size( info );
DWORD len = sizeof(METARECORD) + 10 * sizeof(WORD) + infosize + imagesize;
infosize = bitmap_info_size(info, wUsage); METARECORD *mr = HeapAlloc( GetProcessHeap(), 0, len );
imagesize = DIB_GetDIBImageBytes( info->bmiHeader.biWidth,
info->bmiHeader.biHeight,
info->bmiHeader.biBitCount );
len = sizeof(METARECORD) + 10 * sizeof(WORD) + infosize + imagesize;
mr = HeapAlloc( GetProcessHeap(), 0, len );
if(!mr) return 0; if(!mr) return 0;
mr->rdSize = len / 2; mr->rdSize = len / 2;
...@@ -177,16 +171,10 @@ INT MFDRV_SetDIBitsToDevice( PHYSDEV dev, INT xDst, INT yDst, DWORD cx, ...@@ -177,16 +171,10 @@ INT MFDRV_SetDIBitsToDevice( PHYSDEV dev, INT xDst, INT yDst, DWORD cx,
UINT coloruse ) UINT coloruse )
{ {
DWORD len, infosize, imagesize; DWORD infosize = bitmap_info_size(info, coloruse);
METARECORD *mr; DWORD imagesize = get_dib_image_size( info );
DWORD len = sizeof(METARECORD) + 8 * sizeof(WORD) + infosize + imagesize;
infosize = bitmap_info_size(info, coloruse); METARECORD *mr = HeapAlloc( GetProcessHeap(), 0, len );
imagesize = DIB_GetDIBImageBytes( info->bmiHeader.biWidth,
info->bmiHeader.biHeight,
info->bmiHeader.biBitCount );
len = sizeof(METARECORD) + 8 * sizeof(WORD) + infosize + imagesize;
mr = HeapAlloc( GetProcessHeap(), 0, len );
if(!mr) return 0; if(!mr) return 0;
mr->rdSize = len / 2; mr->rdSize = len / 2;
......
...@@ -249,7 +249,7 @@ INT16 MFDRV_CreateBrushIndirect(PHYSDEV dev, HBRUSH hBrush ) ...@@ -249,7 +249,7 @@ INT16 MFDRV_CreateBrushIndirect(PHYSDEV dev, HBRUSH hBrush )
goto done; goto done;
} }
bmSize = DIB_GetDIBImageBytes(bm.bmWidth, bm.bmHeight, DIB_PAL_COLORS); bmSize = get_dib_stride( bm.bmWidth, bm.bmBitsPixel) * bm.bmHeight;
size = sizeof(METARECORD) + sizeof(WORD) + sizeof(BITMAPINFO) + size = sizeof(METARECORD) + sizeof(WORD) + sizeof(BITMAPINFO) +
sizeof(RGBQUAD) + bmSize; sizeof(RGBQUAD) + bmSize;
...@@ -303,9 +303,7 @@ INT16 MFDRV_CreateBrushIndirect(PHYSDEV dev, HBRUSH hBrush ) ...@@ -303,9 +303,7 @@ INT16 MFDRV_CreateBrushIndirect(PHYSDEV dev, HBRUSH hBrush )
if (info->bmiHeader.biCompression) if (info->bmiHeader.biCompression)
bmSize = info->bmiHeader.biSizeImage; bmSize = info->bmiHeader.biSizeImage;
else else
bmSize = DIB_GetDIBImageBytes(info->bmiHeader.biWidth, bmSize = get_dib_image_size( info );
info->bmiHeader.biHeight,
info->bmiHeader.biBitCount);
biSize = bitmap_info_size(info, LOWORD(logbrush.lbColor)); biSize = bitmap_info_size(info, LOWORD(logbrush.lbColor));
size = sizeof(METARECORD) + biSize + bmSize + 2; size = sizeof(METARECORD) + biSize + bmSize + 2;
mr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); mr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
......
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