- Extended support for BITMAPCOREINFO / BITMAPCOREHEADER structures.
- Always calculate the location of the color table. - CreateCompatibleBitmap: Create a DIB section if necessary. - Added some tests.
This commit is contained in:
parent
7ce764669e
commit
0dd2910eba
|
@ -171,32 +171,83 @@ HBITMAP WINAPI CreateCompatibleBitmap( HDC hdc, INT width, INT height)
|
|||
HBITMAP hbmpRet = 0;
|
||||
DC *dc;
|
||||
|
||||
TRACE("(%p,%d,%d) = \n", hdc, width, height );
|
||||
if (!(dc = DC_GetDCPtr( hdc ))) return 0;
|
||||
if ((width >= 0x10000) || (height >= 0x10000)) {
|
||||
FIXME("got bad width %d or height %d, please look for reason\n",
|
||||
width, height );
|
||||
TRACE("(%p,%d,%d) = \n", hdc, width, height);
|
||||
|
||||
if ((width >= 0x10000) || (height >= 0x10000))
|
||||
{
|
||||
FIXME("got bad width %d or height %d, please look for reason\n",
|
||||
width, height);
|
||||
}
|
||||
else
|
||||
{
|
||||
INT planes, bpp;
|
||||
if (!(dc = DC_GetDCPtr(hdc))) return 0;
|
||||
|
||||
if (GDIMAGIC( dc->header.wMagic ) != MEMORY_DC_MAGIC)
|
||||
{
|
||||
planes = GetDeviceCaps( hdc, PLANES );
|
||||
bpp = GetDeviceCaps( hdc, BITSPIXEL );
|
||||
hbmpRet = CreateBitmap(width, height,
|
||||
GetDeviceCaps(hdc, PLANES),
|
||||
GetDeviceCaps(hdc, BITSPIXEL),
|
||||
NULL);
|
||||
}
|
||||
else /* memory DC, get the depth of the bitmap */
|
||||
else /* Memory DC */
|
||||
{
|
||||
BITMAPOBJ *bmp = GDI_GetObjPtr( dc->hBitmap, BITMAP_MAGIC );
|
||||
planes = bmp->bitmap.bmPlanes;
|
||||
bpp = bmp->bitmap.bmBitsPixel;
|
||||
GDI_ReleaseObj( dc->hBitmap );
|
||||
|
||||
if (!bmp->dib)
|
||||
{
|
||||
/* A device-dependent bitmap is selected in the DC */
|
||||
hbmpRet = CreateBitmap(width, height,
|
||||
bmp->bitmap.bmPlanes,
|
||||
bmp->bitmap.bmBitsPixel,
|
||||
NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* A DIB section is selected in the DC */
|
||||
BITMAPINFO *bi;
|
||||
void *bits;
|
||||
|
||||
/* Allocate memory for a BITMAPINFOHEADER structure and a
|
||||
color table. The maximum number of colors in a color table
|
||||
is 256 which corresponds to a bitmap with depth 8.
|
||||
Bitmaps with higher depths don't have color tables. */
|
||||
bi = HeapAlloc(GetProcessHeap(), 0, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
|
||||
|
||||
if (bi)
|
||||
{
|
||||
bi->bmiHeader.biSize = sizeof(bi->bmiHeader);
|
||||
bi->bmiHeader.biWidth = width;
|
||||
bi->bmiHeader.biHeight = height;
|
||||
bi->bmiHeader.biPlanes = bmp->dib->dsBmih.biPlanes;
|
||||
bi->bmiHeader.biBitCount = bmp->dib->dsBmih.biBitCount;
|
||||
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.biClrUsed = bmp->dib->dsBmih.biClrUsed;
|
||||
bi->bmiHeader.biClrImportant = bmp->dib->dsBmih.biClrImportant;
|
||||
|
||||
if (bi->bmiHeader.biCompression == BI_BITFIELDS)
|
||||
{
|
||||
/* Copy the color masks */
|
||||
CopyMemory(bi->bmiColors, bmp->dib->dsBitfields, 3 * sizeof(DWORD));
|
||||
}
|
||||
else if (bi->bmiHeader.biBitCount <= 8)
|
||||
{
|
||||
/* Copy the color table */
|
||||
GetDIBColorTable(hdc, 0, 256, bi->bmiColors);
|
||||
}
|
||||
|
||||
hbmpRet = CreateDIBSection(hdc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
|
||||
HeapFree(GetProcessHeap(), 0, bi);
|
||||
}
|
||||
}
|
||||
GDI_ReleaseObj(dc->hBitmap);
|
||||
}
|
||||
hbmpRet = CreateBitmap( width, height, planes, bpp, NULL );
|
||||
GDI_ReleaseObj(hdc);
|
||||
}
|
||||
|
||||
TRACE("\t\t%p\n", hbmpRet);
|
||||
GDI_ReleaseObj(hdc);
|
||||
return hbmpRet;
|
||||
}
|
||||
|
||||
|
@ -618,6 +669,8 @@ BOOL WINAPI GetBitmapDimensionEx(
|
|||
* SetBitmapDimensionEx [GDI32.@]
|
||||
*
|
||||
* Assigns dimensions to a bitmap.
|
||||
* MSDN says that this function will fail if hbitmap is a handle created by
|
||||
* CreateDIBSection, but that's not true on Windows 2000.
|
||||
*
|
||||
* RETURNS
|
||||
* Success: TRUE
|
||||
|
|
388
dlls/gdi/dib.c
388
dlls/gdi/dib.c
|
@ -18,6 +18,44 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
Important information:
|
||||
|
||||
* Current Windows versions support two different DIB structures:
|
||||
|
||||
- BITMAPCOREINFO / BITMAPCOREHEADER (legacy structures; used in OS/2)
|
||||
- BITMAPINFO / BITMAPINFOHEADER
|
||||
|
||||
Most Windows API functions taking a BITMAPINFO* / BITMAPINFOHEADER* also
|
||||
accept the old "core" structures, and so must WINE.
|
||||
You can distinguish them by looking at the first member (bcSize/biSize),
|
||||
or use the internal function DIB_GetBitmapInfo.
|
||||
|
||||
|
||||
* The palettes are stored in different formats:
|
||||
|
||||
- BITMAPCOREINFO: Array of RGBTRIPLE
|
||||
- BITMAPINFO: Array of RGBQUAD
|
||||
|
||||
|
||||
* There are even more DIB headers, but they all extend BITMAPINFOHEADER:
|
||||
|
||||
- BITMAPV4HEADER: Introduced in Windows 95 / NT 4.0
|
||||
- BITMAPV5HEADER: Introduced in Windows 98 / 2000
|
||||
|
||||
|
||||
* You should never access the color table using the bmiColors member,
|
||||
because the passed structure may have one of the extended headers
|
||||
mentioned above. Use this to calculate the location:
|
||||
|
||||
BITMAPINFO* info;
|
||||
void* colorPtr = (LPBYTE) info + (WORD) info->bmiHeader.biSize;
|
||||
|
||||
|
||||
* More information:
|
||||
Search for "Bitmap Structures" in MSDN
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -31,6 +69,12 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(bitmap);
|
||||
|
||||
|
||||
/*
|
||||
Some of the following helper functions are duplicated in
|
||||
dlls/x11drv/dib.c
|
||||
*/
|
||||
|
||||
/***********************************************************************
|
||||
* DIB_GetDIBWidthBytes
|
||||
*
|
||||
|
@ -174,12 +218,27 @@ INT WINAPI StretchDIBits(HDC hdc, INT xDst, INT yDst, INT widthDst,
|
|||
{
|
||||
HBITMAP hBitmap, hOldBitmap;
|
||||
HPALETTE hpal = NULL;
|
||||
HDC hdcMem;
|
||||
HDC hdcMem;
|
||||
LONG height;
|
||||
LONG width;
|
||||
WORD bpp;
|
||||
DWORD compr;
|
||||
|
||||
if (DIB_GetBitmapInfo( (BITMAPINFOHEADER*) info, &width, &height, &bpp, &compr ) == -1)
|
||||
{
|
||||
ERR("Invalid bitmap\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (width < 0)
|
||||
{
|
||||
ERR("Bitmap has a negative width\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
GDI_ReleaseObj( hdc );
|
||||
hdcMem = CreateCompatibleDC( hdc );
|
||||
hBitmap = CreateCompatibleBitmap(hdc, info->bmiHeader.biWidth,
|
||||
info->bmiHeader.biHeight);
|
||||
hBitmap = CreateCompatibleBitmap(hdc, width, height);
|
||||
hOldBitmap = SelectObject( hdcMem, hBitmap );
|
||||
if(wUsage == DIB_PAL_COLORS)
|
||||
{
|
||||
|
@ -206,18 +265,17 @@ INT WINAPI StretchDIBits(HDC hdc, INT xDst, INT yDst, INT widthDst,
|
|||
*/
|
||||
|
||||
/* copy existing bitmap from destination dc */
|
||||
StretchBlt( hdcMem, xSrc, abs(info->bmiHeader.biHeight) - heightSrc - ySrc,
|
||||
StretchBlt( hdcMem, xSrc, abs(height) - heightSrc - ySrc,
|
||||
widthSrc, heightSrc, hdc, xDst, yDst, widthDst, heightDst,
|
||||
dwRop );
|
||||
}
|
||||
|
||||
SetDIBits(hdcMem, hBitmap, 0, info->bmiHeader.biHeight, bits,
|
||||
info, wUsage);
|
||||
SetDIBits(hdcMem, hBitmap, 0, height, bits, info, wUsage);
|
||||
|
||||
/* Origin for DIBitmap may be bottom left (positive biHeight) or top
|
||||
left (negative biHeight) */
|
||||
StretchBlt( hdc, xDst, yDst, widthDst, heightDst,
|
||||
hdcMem, xSrc, abs(info->bmiHeader.biHeight) - heightSrc - ySrc,
|
||||
hdcMem, xSrc, abs(height) - heightSrc - ySrc,
|
||||
widthSrc, heightSrc, dwRop );
|
||||
if(hpal)
|
||||
SelectPalette(hdcMem, hpal, FALSE);
|
||||
|
@ -346,8 +404,8 @@ UINT WINAPI GetDIBColorTable( HDC hdc, UINT startpos, UINT entries, RGBQUAD *col
|
|||
NB. RGBQUAD and PALETTEENTRY have different orderings of red, green
|
||||
and blue - sigh */
|
||||
|
||||
static RGBQUAD EGAColors[16] = {
|
||||
/* rgbBlue, rgbGreen, rgbRed, rgbReserverd */
|
||||
static RGBQUAD EGAColorsQuads[16] = {
|
||||
/* rgbBlue, rgbGreen, rgbRed, rgbReserved */
|
||||
{ 0x00, 0x00, 0x00, 0x00 },
|
||||
{ 0x00, 0x00, 0x80, 0x00 },
|
||||
{ 0x00, 0x80, 0x00, 0x00 },
|
||||
|
@ -366,9 +424,28 @@ static RGBQUAD EGAColors[16] = {
|
|||
{ 0xff, 0xff, 0xff, 0x00 }
|
||||
};
|
||||
|
||||
static RGBTRIPLE EGAColorsTriples[16] = {
|
||||
/* rgbBlue, rgbGreen, rgbRed */
|
||||
{ 0x00, 0x00, 0x00 },
|
||||
{ 0x00, 0x00, 0x80 },
|
||||
{ 0x00, 0x80, 0x00 },
|
||||
{ 0x00, 0x80, 0x80 },
|
||||
{ 0x80, 0x00, 0x00 },
|
||||
{ 0x80, 0x00, 0x80 },
|
||||
{ 0x80, 0x80, 0x00 },
|
||||
{ 0x80, 0x80, 0x80 },
|
||||
{ 0xc0, 0xc0, 0xc0 },
|
||||
{ 0x00, 0x00, 0xff },
|
||||
{ 0x00, 0xff, 0x00 },
|
||||
{ 0x00, 0xff, 0xff },
|
||||
{ 0xff, 0x00, 0x00 } ,
|
||||
{ 0xff, 0x00, 0xff },
|
||||
{ 0xff, 0xff, 0x00 },
|
||||
{ 0xff, 0xff, 0xff }
|
||||
};
|
||||
|
||||
static RGBQUAD DefLogPalette[20] = { /* Copy of Default Logical Palette */
|
||||
/* rgbBlue, rgbGreen, rgbRed, rgbReserverd */
|
||||
static RGBQUAD DefLogPaletteQuads[20] = { /* Copy of Default Logical Palette */
|
||||
/* rgbBlue, rgbGreen, rgbRed, rgbReserved */
|
||||
{ 0x00, 0x00, 0x00, 0x00 },
|
||||
{ 0x00, 0x00, 0x80, 0x00 },
|
||||
{ 0x00, 0x80, 0x00, 0x00 },
|
||||
|
@ -391,6 +468,30 @@ static RGBQUAD DefLogPalette[20] = { /* Copy of Default Logical Palette */
|
|||
{ 0xff, 0xff, 0xff, 0x00 }
|
||||
};
|
||||
|
||||
static RGBTRIPLE DefLogPaletteTriples[20] = { /* Copy of Default Logical Palette */
|
||||
/* rgbBlue, rgbGreen, rgbRed */
|
||||
{ 0x00, 0x00, 0x00 },
|
||||
{ 0x00, 0x00, 0x80 },
|
||||
{ 0x00, 0x80, 0x00 },
|
||||
{ 0x00, 0x80, 0x80 },
|
||||
{ 0x80, 0x00, 0x00 },
|
||||
{ 0x80, 0x00, 0x80 },
|
||||
{ 0x80, 0x80, 0x00 },
|
||||
{ 0xc0, 0xc0, 0xc0 },
|
||||
{ 0xc0, 0xdc, 0xc0 },
|
||||
{ 0xf0, 0xca, 0xa6 },
|
||||
{ 0xf0, 0xfb, 0xff },
|
||||
{ 0xa4, 0xa0, 0xa0 },
|
||||
{ 0x80, 0x80, 0x80 },
|
||||
{ 0x00, 0x00, 0xf0 },
|
||||
{ 0x00, 0xff, 0x00 },
|
||||
{ 0x00, 0xff, 0xff },
|
||||
{ 0xff, 0x00, 0x00 },
|
||||
{ 0xff, 0x00, 0xff },
|
||||
{ 0xff, 0xff, 0x00 },
|
||||
{ 0xff, 0xff, 0xff}
|
||||
};
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* GetDIBits [GDI32.@]
|
||||
|
@ -416,8 +517,25 @@ INT WINAPI GetDIBits(
|
|||
BITMAPOBJ * bmp;
|
||||
int i;
|
||||
HDC memdc;
|
||||
int bitmap_type;
|
||||
BOOL core_header;
|
||||
LONG width;
|
||||
LONG height;
|
||||
WORD bpp;
|
||||
DWORD compr;
|
||||
void* colorPtr;
|
||||
RGBTRIPLE* rgbTriples;
|
||||
RGBQUAD* rgbQuads;
|
||||
|
||||
if (!info) return 0;
|
||||
|
||||
bitmap_type = DIB_GetBitmapInfo( (BITMAPINFOHEADER*) info, &width, &height, &bpp, &compr);
|
||||
if (bitmap_type == -1)
|
||||
{
|
||||
ERR("Invalid bitmap format\n");
|
||||
return 0;
|
||||
}
|
||||
core_header = (bitmap_type == 0);
|
||||
memdc = CreateCompatibleDC(hdc);
|
||||
if (!(dc = DC_GetDCUpdate( hdc )))
|
||||
{
|
||||
|
@ -431,30 +549,57 @@ INT WINAPI GetDIBits(
|
|||
return 0;
|
||||
}
|
||||
|
||||
colorPtr = (LPBYTE) info + (WORD) info->bmiHeader.biSize;
|
||||
rgbTriples = (RGBTRIPLE *) colorPtr;
|
||||
rgbQuads = (RGBQUAD *) colorPtr;
|
||||
|
||||
/* Transfer color info */
|
||||
|
||||
if (info->bmiHeader.biBitCount <= 8 && info->bmiHeader.biBitCount > 0 ) {
|
||||
|
||||
info->bmiHeader.biClrUsed = 0;
|
||||
if (bpp <= 8 && bpp > 0)
|
||||
{
|
||||
if (!core_header) info->bmiHeader.biClrUsed = 0;
|
||||
|
||||
/* If the bitmap object already has a dib section at the
|
||||
same color depth then get the color map from it */
|
||||
if (bmp->dib && bmp->dib->dsBm.bmBitsPixel == info->bmiHeader.biBitCount) {
|
||||
if (bmp->dib && bmp->dib->dsBm.bmBitsPixel == bpp) {
|
||||
if(coloruse == DIB_RGB_COLORS) {
|
||||
HBITMAP oldbm;
|
||||
oldbm = SelectObject(memdc, hbitmap);
|
||||
GetDIBColorTable(memdc, 0, 1 << info->bmiHeader.biBitCount, info->bmiColors);
|
||||
HBITMAP oldbm = SelectObject(memdc, hbitmap);
|
||||
unsigned int colors = 1 << bpp;
|
||||
|
||||
if (core_header)
|
||||
{
|
||||
/* Convert the color table (RGBQUAD to RGBTRIPLE) */
|
||||
RGBQUAD* buffer = HeapAlloc(GetProcessHeap(), 0, colors * sizeof(RGBQUAD));
|
||||
|
||||
if (buffer)
|
||||
{
|
||||
RGBTRIPLE* index = rgbTriples;
|
||||
GetDIBColorTable(memdc, 0, colors, buffer);
|
||||
|
||||
for (i=0; i < colors; i++, index++)
|
||||
{
|
||||
index->rgbtRed = buffer[i].rgbRed;
|
||||
index->rgbtGreen = buffer[i].rgbGreen;
|
||||
index->rgbtBlue = buffer[i].rgbBlue;
|
||||
}
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, buffer);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GetDIBColorTable(memdc, 0, colors, colorPtr);
|
||||
}
|
||||
SelectObject(memdc, oldbm);
|
||||
}
|
||||
else {
|
||||
WORD *index = (WORD*)info->bmiColors;
|
||||
int i;
|
||||
WORD *index = colorPtr;
|
||||
for(i = 0; i < 1 << info->bmiHeader.biBitCount; i++, index++)
|
||||
*index = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(info->bmiHeader.biBitCount >= bmp->bitmap.bmBitsPixel) {
|
||||
if(bpp >= bmp->bitmap.bmBitsPixel) {
|
||||
/* Generate the color map from the selected palette */
|
||||
PALETTEENTRY * palEntry;
|
||||
PALETTEOBJ * palette;
|
||||
|
@ -467,48 +612,93 @@ INT WINAPI GetDIBits(
|
|||
palEntry = palette->logpalette.palPalEntry;
|
||||
for (i = 0; i < (1 << bmp->bitmap.bmBitsPixel); i++, palEntry++) {
|
||||
if (coloruse == DIB_RGB_COLORS) {
|
||||
info->bmiColors[i].rgbRed = palEntry->peRed;
|
||||
info->bmiColors[i].rgbGreen = palEntry->peGreen;
|
||||
info->bmiColors[i].rgbBlue = palEntry->peBlue;
|
||||
info->bmiColors[i].rgbReserved = 0;
|
||||
if (core_header)
|
||||
{
|
||||
rgbTriples[i].rgbtRed = palEntry->peRed;
|
||||
rgbTriples[i].rgbtGreen = palEntry->peGreen;
|
||||
rgbTriples[i].rgbtBlue = palEntry->peBlue;
|
||||
}
|
||||
else
|
||||
{
|
||||
rgbQuads[i].rgbRed = palEntry->peRed;
|
||||
rgbQuads[i].rgbGreen = palEntry->peGreen;
|
||||
rgbQuads[i].rgbBlue = palEntry->peBlue;
|
||||
rgbQuads[i].rgbReserved = 0;
|
||||
}
|
||||
}
|
||||
else ((WORD *)info->bmiColors)[i] = (WORD)i;
|
||||
else ((WORD *)colorPtr)[i] = (WORD)i;
|
||||
}
|
||||
GDI_ReleaseObj( dc->hPalette );
|
||||
} else {
|
||||
switch (info->bmiHeader.biBitCount) {
|
||||
switch (bpp) {
|
||||
case 1:
|
||||
info->bmiColors[0].rgbRed = info->bmiColors[0].rgbGreen =
|
||||
info->bmiColors[0].rgbBlue = 0;
|
||||
info->bmiColors[0].rgbReserved = 0;
|
||||
info->bmiColors[1].rgbRed = info->bmiColors[1].rgbGreen =
|
||||
info->bmiColors[1].rgbBlue = 0xff;
|
||||
info->bmiColors[1].rgbReserved = 0;
|
||||
if (core_header)
|
||||
{
|
||||
rgbTriples[0].rgbtRed = rgbTriples[0].rgbtGreen =
|
||||
rgbTriples[0].rgbtBlue = 0;
|
||||
rgbTriples[1].rgbtRed = rgbTriples[1].rgbtGreen =
|
||||
rgbTriples[1].rgbtBlue = 0xff;
|
||||
}
|
||||
else
|
||||
{
|
||||
rgbQuads[0].rgbRed = rgbQuads[0].rgbGreen =
|
||||
rgbQuads[0].rgbBlue = 0;
|
||||
rgbQuads[0].rgbReserved = 0;
|
||||
rgbQuads[1].rgbRed = rgbQuads[1].rgbGreen =
|
||||
rgbQuads[1].rgbBlue = 0xff;
|
||||
rgbQuads[1].rgbReserved = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
memcpy(info->bmiColors, EGAColors, sizeof(EGAColors));
|
||||
if (core_header)
|
||||
memcpy(colorPtr, EGAColorsTriples, sizeof(EGAColorsTriples));
|
||||
else
|
||||
memcpy(colorPtr, EGAColorsQuads, sizeof(EGAColorsQuads));
|
||||
|
||||
break;
|
||||
|
||||
case 8:
|
||||
{
|
||||
INT r, g, b;
|
||||
RGBQUAD *color;
|
||||
if (core_header)
|
||||
{
|
||||
INT r, g, b;
|
||||
RGBTRIPLE *color;
|
||||
|
||||
memcpy(info->bmiColors, DefLogPalette,
|
||||
10 * sizeof(RGBQUAD));
|
||||
memcpy(info->bmiColors + 246, DefLogPalette + 10,
|
||||
10 * sizeof(RGBQUAD));
|
||||
color = info->bmiColors + 10;
|
||||
for(r = 0; r <= 5; r++) /* FIXME */
|
||||
for(g = 0; g <= 5; g++)
|
||||
for(b = 0; b <= 5; b++) {
|
||||
color->rgbRed = (r * 0xff) / 5;
|
||||
color->rgbGreen = (g * 0xff) / 5;
|
||||
color->rgbBlue = (b * 0xff) / 5;
|
||||
color->rgbReserved = 0;
|
||||
color++;
|
||||
}
|
||||
memcpy(rgbTriples, DefLogPaletteTriples,
|
||||
10 * sizeof(RGBTRIPLE));
|
||||
memcpy(rgbTriples + 246, DefLogPaletteTriples + 10,
|
||||
10 * sizeof(RGBTRIPLE));
|
||||
color = rgbTriples + 10;
|
||||
for(r = 0; r <= 5; r++) /* FIXME */
|
||||
for(g = 0; g <= 5; g++)
|
||||
for(b = 0; b <= 5; b++) {
|
||||
color->rgbtRed = (r * 0xff) / 5;
|
||||
color->rgbtGreen = (g * 0xff) / 5;
|
||||
color->rgbtBlue = (b * 0xff) / 5;
|
||||
color++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
INT r, g, b;
|
||||
RGBQUAD *color;
|
||||
|
||||
memcpy(rgbQuads, DefLogPaletteQuads,
|
||||
10 * sizeof(RGBQUAD));
|
||||
memcpy(rgbQuads + 246, DefLogPaletteQuads + 10,
|
||||
10 * sizeof(RGBQUAD));
|
||||
color = rgbQuads + 10;
|
||||
for(r = 0; r <= 5; r++) /* FIXME */
|
||||
for(g = 0; g <= 5; g++)
|
||||
for(b = 0; b <= 5; b++) {
|
||||
color->rgbRed = (r * 0xff) / 5;
|
||||
color->rgbGreen = (g * 0xff) / 5;
|
||||
color->rgbBlue = (b * 0xff) / 5;
|
||||
color->rgbReserved = 0;
|
||||
color++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -518,22 +708,22 @@ INT WINAPI GetDIBits(
|
|||
if (bits && lines)
|
||||
{
|
||||
/* If the bitmap object already have a dib section that contains image data, get the bits from it */
|
||||
if(bmp->dib && bmp->dib->dsBm.bmBitsPixel >= 15 && info->bmiHeader.biBitCount >= 15)
|
||||
if(bmp->dib && bmp->dib->dsBm.bmBitsPixel >= 15 && bpp >= 15)
|
||||
{
|
||||
/*FIXME: Only RGB dibs supported for now */
|
||||
unsigned int srcwidth = bmp->dib->dsBm.bmWidth, srcwidthb = bmp->dib->dsBm.bmWidthBytes;
|
||||
unsigned int dstwidth = info->bmiHeader.biWidth;
|
||||
int dstwidthb = DIB_GetDIBWidthBytes( info->bmiHeader.biWidth, info->bmiHeader.biBitCount );
|
||||
unsigned int dstwidth = width;
|
||||
int dstwidthb = DIB_GetDIBWidthBytes( width, bpp );
|
||||
LPBYTE dbits = bits, sbits = (LPBYTE) bmp->dib->dsBm.bmBits + (startscan * srcwidthb);
|
||||
unsigned int x, y, width, widthb;
|
||||
|
||||
if ((info->bmiHeader.biHeight < 0) ^ (bmp->dib->dsBmih.biHeight < 0))
|
||||
if ((height < 0) ^ (bmp->dib->dsBmih.biHeight < 0))
|
||||
{
|
||||
dbits = (LPBYTE)bits + (dstwidthb * (lines-1));
|
||||
dstwidthb = -dstwidthb;
|
||||
}
|
||||
|
||||
switch( info->bmiHeader.biBitCount ) {
|
||||
switch( bpp ) {
|
||||
|
||||
case 15:
|
||||
case 16: /* 16 bpp dstDIB */
|
||||
|
@ -734,35 +924,41 @@ INT WINAPI GetDIBits(
|
|||
}
|
||||
}
|
||||
}
|
||||
else if( info->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER) )
|
||||
else
|
||||
{
|
||||
/* fill in struct members */
|
||||
|
||||
if( info->bmiHeader.biBitCount == 0)
|
||||
{
|
||||
info->bmiHeader.biWidth = bmp->bitmap.bmWidth;
|
||||
info->bmiHeader.biHeight = bmp->bitmap.bmHeight;
|
||||
info->bmiHeader.biPlanes = 1;
|
||||
info->bmiHeader.biBitCount = bmp->bitmap.bmBitsPixel;
|
||||
info->bmiHeader.biSizeImage =
|
||||
DIB_GetDIBImageBytes( bmp->bitmap.bmWidth,
|
||||
bmp->bitmap.bmHeight,
|
||||
bmp->bitmap.bmBitsPixel );
|
||||
info->bmiHeader.biCompression = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
info->bmiHeader.biSizeImage = DIB_GetDIBImageBytes(
|
||||
info->bmiHeader.biWidth,
|
||||
info->bmiHeader.biHeight,
|
||||
info->bmiHeader.biBitCount );
|
||||
}
|
||||
lines = info->bmiHeader.biHeight;
|
||||
if (bpp == 0)
|
||||
{
|
||||
if (core_header)
|
||||
{
|
||||
BITMAPCOREHEADER* coreheader = (BITMAPCOREHEADER*) info;
|
||||
coreheader->bcWidth = bmp->bitmap.bmWidth;
|
||||
coreheader->bcHeight = bmp->bitmap.bmHeight;
|
||||
coreheader->bcPlanes = 1;
|
||||
coreheader->bcBitCount = bmp->bitmap.bmBitsPixel;
|
||||
}
|
||||
else
|
||||
{
|
||||
info->bmiHeader.biWidth = bmp->bitmap.bmWidth;
|
||||
info->bmiHeader.biHeight = bmp->bitmap.bmHeight;
|
||||
info->bmiHeader.biPlanes = 1;
|
||||
info->bmiHeader.biBitCount = bmp->bitmap.bmBitsPixel;
|
||||
info->bmiHeader.biSizeImage =
|
||||
DIB_GetDIBImageBytes( bmp->bitmap.bmWidth,
|
||||
bmp->bitmap.bmHeight,
|
||||
bmp->bitmap.bmBitsPixel );
|
||||
info->bmiHeader.biCompression = 0;
|
||||
}
|
||||
lines = abs(bmp->bitmap.bmHeight);
|
||||
}
|
||||
}
|
||||
|
||||
TRACE("biSizeImage = %ld, biWidth = %ld, biHeight = %ld\n",
|
||||
info->bmiHeader.biSizeImage, info->bmiHeader.biWidth,
|
||||
info->bmiHeader.biHeight);
|
||||
if (!core_header)
|
||||
{
|
||||
TRACE("biSizeImage = %ld, ", info->bmiHeader.biSizeImage);
|
||||
}
|
||||
TRACE("biWidth = %ld, biHeight = %ld\n", width, height);
|
||||
|
||||
GDI_ReleaseObj( hdc );
|
||||
GDI_ReleaseObj( hbitmap );
|
||||
|
@ -841,15 +1037,33 @@ HBITMAP16 WINAPI CreateDIBSection16 (HDC16 hdc, const BITMAPINFO *bmi, UINT16 us
|
|||
if (bmp && bmp->dib && bits32)
|
||||
{
|
||||
const BITMAPINFOHEADER *bi = &bmi->bmiHeader;
|
||||
INT height = bi->biHeight >= 0 ? bi->biHeight : -bi->biHeight;
|
||||
INT width_bytes = DIB_GetDIBWidthBytes(bi->biWidth, bi->biBitCount);
|
||||
INT size = (bi->biSizeImage && bi->biCompression != BI_RGB) ?
|
||||
bi->biSizeImage : width_bytes * height;
|
||||
LONG width, height;
|
||||
WORD bpp;
|
||||
DWORD compr;
|
||||
BOOL core_header;
|
||||
INT width_bytes;
|
||||
INT size;
|
||||
WORD count, sel;
|
||||
int i;
|
||||
|
||||
core_header = (DIB_GetBitmapInfo(bi, &width, &height, &bpp, &compr) == 0);
|
||||
|
||||
height = height >= 0 ? height : -height;
|
||||
width_bytes = DIB_GetDIBWidthBytes(width, bpp);
|
||||
|
||||
if (core_header)
|
||||
{
|
||||
size = width_bytes * height;
|
||||
}
|
||||
else
|
||||
{
|
||||
size = (bi->biSizeImage && compr != BI_RGB) ?
|
||||
bi->biSizeImage : width_bytes * height;
|
||||
}
|
||||
|
||||
/* calculate number of sel's needed for size with 64K steps */
|
||||
WORD count = (size + 0xffff) / 0x10000;
|
||||
WORD sel = AllocSelectorArray16(count);
|
||||
int i;
|
||||
count = (size + 0xffff) / 0x10000;
|
||||
sel = AllocSelectorArray16(count);
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
|
|
|
@ -160,7 +160,11 @@ static void test_dibsections(void)
|
|||
HDC hdc, hdcmem, hdcmem2;
|
||||
HBITMAP hdib, oldbm, hdib2, oldbm2;
|
||||
char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
|
||||
char bcibuf[sizeof(BITMAPCOREINFO) + 256 * sizeof(RGBTRIPLE)];
|
||||
BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
|
||||
BITMAPCOREINFO *pbci = (BITMAPCOREINFO *)bcibuf;
|
||||
HBITMAP hcoredib;
|
||||
char coreBits[256];
|
||||
BYTE *bits;
|
||||
RGBQUAD rgb[256];
|
||||
int ret;
|
||||
|
@ -188,6 +192,37 @@ static void test_dibsections(void)
|
|||
hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
|
||||
ok(hdib != NULL, "CreateDIBSection failed\n");
|
||||
|
||||
/* Test if the old BITMAPCOREINFO structure is supported */
|
||||
|
||||
pbci->bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
|
||||
pbci->bmciHeader.bcBitCount = 0;
|
||||
|
||||
ret = GetDIBits(hdc, hdib, 0, 16, NULL, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
|
||||
ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
|
||||
ok((pbci->bmciHeader.bcWidth == 16) && (pbci->bmciHeader.bcHeight == 16)
|
||||
&& (pbci->bmciHeader.bcBitCount == 1) && (pbci->bmciHeader.bcPlanes == 1),
|
||||
"GetDIBits did't fill in the BITMAPCOREHEADER structure properly\n");
|
||||
|
||||
ret = GetDIBits(hdc, hdib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
|
||||
ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
|
||||
ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
|
||||
(pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
|
||||
(pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
|
||||
"The color table has not been translated to the old BITMAPCOREINFO format\n");
|
||||
|
||||
hcoredib = CreateDIBSection(hdc, (BITMAPINFO*) pbci, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
|
||||
ok(hcoredib != NULL, "CreateDIBSection failed with a BITMAPCOREINFO\n");
|
||||
|
||||
ZeroMemory(pbci->bmciColors, 256 * sizeof(RGBTRIPLE));
|
||||
ret = GetDIBits(hdc, hcoredib, 0, 16, &coreBits, (BITMAPINFO*) pbci, DIB_RGB_COLORS);
|
||||
ok(ret, "GetDIBits doesn't work with a BITMAPCOREHEADER\n");
|
||||
ok((pbci->bmciColors[0].rgbtRed == 0xff) && (pbci->bmciColors[0].rgbtGreen == 0) &&
|
||||
(pbci->bmciColors[0].rgbtBlue == 0) && (pbci->bmciColors[1].rgbtRed == 0) &&
|
||||
(pbci->bmciColors[1].rgbtGreen == 0) && (pbci->bmciColors[1].rgbtBlue == 0xff),
|
||||
"The color table has not been translated to the old BITMAPCOREINFO format\n");
|
||||
|
||||
DeleteObject(hcoredib);
|
||||
|
||||
hdcmem = CreateCompatibleDC(hdc);
|
||||
oldbm = SelectObject(hdcmem, hdib);
|
||||
|
||||
|
|
|
@ -83,6 +83,12 @@ enum Rle_EscapeCodes
|
|||
RLE_DELTA = 2 /* Delta */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
Some of the following helper functions are duplicated in
|
||||
dlls/gdi/dib.c
|
||||
*/
|
||||
|
||||
/***********************************************************************
|
||||
* X11DRV_DIB_GetXImageWidthBytes
|
||||
*
|
||||
|
@ -139,6 +145,17 @@ static int X11DRV_DIB_GetDIBWidthBytes( int width, int depth )
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* X11DRV_DIB_GetDIBImageBytes
|
||||
*
|
||||
* Return the number of bytes used to hold the image in a DIB bitmap.
|
||||
*/
|
||||
static int X11DRV_DIB_GetDIBImageBytes( int width, int height, int depth )
|
||||
{
|
||||
return X11DRV_DIB_GetDIBWidthBytes( width, depth ) * abs( height );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* X11DRV_DIB_BitmapInfoSize
|
||||
*
|
||||
|
@ -146,7 +163,7 @@ static int X11DRV_DIB_GetDIBWidthBytes( int width, int depth )
|
|||
*/
|
||||
int X11DRV_DIB_BitmapInfoSize( const BITMAPINFO * info, WORD coloruse )
|
||||
{
|
||||
int colors;
|
||||
unsigned int colors;
|
||||
|
||||
if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
|
||||
{
|
||||
|
@ -187,29 +204,34 @@ XImage *X11DRV_DIB_CreateXImage( int width, int height, int depth )
|
|||
|
||||
|
||||
/***********************************************************************
|
||||
* DIB_GetBitmapInfo
|
||||
* DIB_GetBitmapInfoEx
|
||||
*
|
||||
* Get the info from a bitmap header.
|
||||
* Return 1 for INFOHEADER, 0 for COREHEADER, -1 for error.
|
||||
*/
|
||||
static int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, DWORD *width,
|
||||
int *height, WORD *bpp, WORD *compr )
|
||||
static int DIB_GetBitmapInfoEx( const BITMAPINFOHEADER *header, LONG *width,
|
||||
LONG *height, WORD *planes, WORD *bpp,
|
||||
WORD *compr, DWORD *size )
|
||||
{
|
||||
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;
|
||||
}
|
||||
ERR("(%ld): unknown/wrong size for header\n", header->biSize );
|
||||
|
@ -217,6 +239,22 @@ static int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, DWORD *width,
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* DIB_GetBitmapInfo
|
||||
*
|
||||
* Get the info from a bitmap header.
|
||||
* Return 1 for INFOHEADER, 0 for COREHEADER, -1 for error.
|
||||
*/
|
||||
static int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, LONG *width,
|
||||
LONG *height, WORD *bpp, WORD *compr )
|
||||
{
|
||||
WORD planes;
|
||||
DWORD size;
|
||||
|
||||
return DIB_GetBitmapInfoEx( header, width, height, &planes, bpp, compr, &size);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* X11DRV_DIB_GenColorMap
|
||||
*
|
||||
|
@ -285,24 +323,25 @@ int *X11DRV_DIB_GenColorMap( X11DRV_PDEVICE *physDev, int *colorMapping,
|
|||
int *X11DRV_DIB_BuildColorMap( X11DRV_PDEVICE *physDev, WORD coloruse, WORD depth,
|
||||
const BITMAPINFO *info, int *nColors )
|
||||
{
|
||||
int colors;
|
||||
unsigned int colors;
|
||||
BOOL isInfo;
|
||||
const void *colorPtr;
|
||||
int *colorMapping;
|
||||
|
||||
if ((isInfo = (info->bmiHeader.biSize != sizeof(BITMAPCOREHEADER))))
|
||||
isInfo = info->bmiHeader.biSize != sizeof(BITMAPCOREHEADER);
|
||||
|
||||
if (isInfo)
|
||||
{
|
||||
/* assume BITMAPINFOHEADER */
|
||||
colors = info->bmiHeader.biClrUsed;
|
||||
if (!colors) colors = 1 << info->bmiHeader.biBitCount;
|
||||
colorPtr = info->bmiColors;
|
||||
}
|
||||
else /* BITMAPCOREHEADER */
|
||||
else
|
||||
{
|
||||
colors = 1 << ((BITMAPCOREHEADER *)info)->bcBitCount;
|
||||
colorPtr = (WORD *)((BITMAPCOREINFO *)info)->bmciColors;
|
||||
}
|
||||
|
||||
colorPtr = (LPBYTE) info + (WORD) info->bmiHeader.biSize;
|
||||
|
||||
if (colors > 256)
|
||||
{
|
||||
ERR("called with >256 colors!\n");
|
||||
|
@ -333,10 +372,19 @@ static RGBQUAD *X11DRV_DIB_BuildColorTable( X11DRV_PDEVICE *physDev, WORD coloru
|
|||
const BITMAPINFO *info )
|
||||
{
|
||||
RGBQUAD *colorTable;
|
||||
int colors, i;
|
||||
unsigned int colors;
|
||||
int i;
|
||||
BOOL core_info = info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER);
|
||||
|
||||
colors = info->bmiHeader.biClrUsed;
|
||||
if (!colors) colors = 1 << info->bmiHeader.biBitCount;
|
||||
if (core_info)
|
||||
{
|
||||
colors = 1 << ((BITMAPCOREINFO*) info)->bmciHeader.bcBitCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
colors = info->bmiHeader.biClrUsed;
|
||||
if (!colors) colors = 1 << info->bmiHeader.biBitCount;
|
||||
}
|
||||
|
||||
if (colors > 256) {
|
||||
ERR("called with >256 colors!\n");
|
||||
|
@ -347,14 +395,33 @@ static RGBQUAD *X11DRV_DIB_BuildColorTable( X11DRV_PDEVICE *physDev, WORD coloru
|
|||
return NULL;
|
||||
|
||||
if(coloruse == DIB_RGB_COLORS)
|
||||
memcpy(colorTable, info->bmiColors, colors * sizeof(RGBQUAD));
|
||||
else {
|
||||
{
|
||||
if (core_info)
|
||||
{
|
||||
/* Convert RGBTRIPLEs to RGBQUADs */
|
||||
for (i=0; i < colors; i++)
|
||||
{
|
||||
colorTable[i].rgbRed = ((BITMAPCOREINFO*) info)->bmciColors[i].rgbtRed;
|
||||
colorTable[i].rgbGreen = ((BITMAPCOREINFO*) info)->bmciColors[i].rgbtGreen;
|
||||
colorTable[i].rgbBlue = ((BITMAPCOREINFO*) info)->bmciColors[i].rgbtBlue;
|
||||
colorTable[i].rgbReserved = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(colorTable, (LPBYTE) info + (WORD) info->bmiHeader.biSize, colors * sizeof(RGBQUAD));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
HPALETTE hpal = GetCurrentObject(physDev->hdc, OBJ_PAL);
|
||||
PALETTEENTRY pal_ents[256];
|
||||
WORD *index;
|
||||
WORD *index = (WORD*) ((LPBYTE) info + (WORD) info->bmiHeader.biSize);
|
||||
|
||||
GetPaletteEntries(hpal, 0, 256, pal_ents);
|
||||
for(i = 0, index = (WORD*)info->bmiColors; i < colors; i++, index++) {
|
||||
|
||||
for(i = 0; i < colors; i++, index++)
|
||||
{
|
||||
colorTable[i].rgbRed = pal_ents[*index].peRed;
|
||||
colorTable[i].rgbGreen = pal_ents[*index].peGreen;
|
||||
colorTable[i].rgbBlue = pal_ents[*index].peBlue;
|
||||
|
@ -370,7 +437,7 @@ static RGBQUAD *X11DRV_DIB_BuildColorTable( X11DRV_PDEVICE *physDev, WORD coloru
|
|||
*/
|
||||
int X11DRV_DIB_MapColor( int *physMap, int nPhysMap, int phys, int oldcol )
|
||||
{
|
||||
int color;
|
||||
unsigned int color;
|
||||
|
||||
if ((oldcol < nPhysMap) && (physMap[oldcol] == phys))
|
||||
return oldcol;
|
||||
|
@ -3626,15 +3693,16 @@ INT X11DRV_SetDIBitsToDevice( X11DRV_PDEVICE *physDev, INT xDest, INT yDest, DWO
|
|||
const BITMAPINFO *info, UINT coloruse )
|
||||
{
|
||||
X11DRV_DIB_IMAGEBITS_DESCR descr;
|
||||
DWORD width;
|
||||
INT result;
|
||||
int height;
|
||||
LONG width, height;
|
||||
BOOL top_down;
|
||||
POINT pt;
|
||||
void* colorPtr;
|
||||
|
||||
if (DIB_GetBitmapInfo( &info->bmiHeader, &width, &height,
|
||||
&descr.infoBpp, &descr.compression ) == -1)
|
||||
return 0;
|
||||
|
||||
top_down = (height < 0);
|
||||
if (top_down) height = -height;
|
||||
|
||||
|
@ -3685,6 +3753,8 @@ INT X11DRV_SetDIBitsToDevice( X11DRV_PDEVICE *physDev, INT xDest, INT yDest, DWO
|
|||
XSetFunction(gdi_display, physDev->gc, X11DRV_XROPfunction[GetROP2(physDev->hdc) - 1]);
|
||||
wine_tsx11_unlock();
|
||||
|
||||
colorPtr = (LPBYTE) info + (WORD) info->bmiHeader.biSize;
|
||||
|
||||
switch (descr.infoBpp)
|
||||
{
|
||||
case 1:
|
||||
|
@ -3698,17 +3768,17 @@ INT X11DRV_SetDIBitsToDevice( X11DRV_PDEVICE *physDev, INT xDest, INT yDest, DWO
|
|||
break;
|
||||
case 15:
|
||||
case 16:
|
||||
descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00;
|
||||
descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x03e0;
|
||||
descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x001f;
|
||||
descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *) colorPtr : 0x7c00;
|
||||
descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)colorPtr + 1) : 0x03e0;
|
||||
descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)colorPtr + 2) : 0x001f;
|
||||
descr.colorMap = 0;
|
||||
break;
|
||||
|
||||
case 24:
|
||||
case 32:
|
||||
descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0xff0000;
|
||||
descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x00ff00;
|
||||
descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x0000ff;
|
||||
descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *) colorPtr : 0xff0000;
|
||||
descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)colorPtr + 1) : 0x00ff00;
|
||||
descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)colorPtr + 2) : 0x0000ff;
|
||||
descr.colorMap = 0;
|
||||
break;
|
||||
}
|
||||
|
@ -3750,8 +3820,9 @@ INT X11DRV_SetDIBits( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, UINT startscan,
|
|||
{
|
||||
X11DRV_DIB_IMAGEBITS_DESCR descr;
|
||||
BITMAPOBJ *bmp;
|
||||
int height, tmpheight;
|
||||
LONG height, tmpheight;
|
||||
INT result;
|
||||
void* colorPtr;
|
||||
|
||||
descr.physDev = physDev;
|
||||
|
||||
|
@ -3768,6 +3839,8 @@ INT X11DRV_SetDIBits( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, UINT startscan,
|
|||
|
||||
if (startscan + lines > height) lines = height - startscan;
|
||||
|
||||
colorPtr = (LPBYTE) info + (WORD) info->bmiHeader.biSize;
|
||||
|
||||
switch (descr.infoBpp)
|
||||
{
|
||||
case 1:
|
||||
|
@ -3786,17 +3859,17 @@ INT X11DRV_SetDIBits( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, UINT startscan,
|
|||
break;
|
||||
case 15:
|
||||
case 16:
|
||||
descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00;
|
||||
descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x03e0;
|
||||
descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x001f;
|
||||
descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *) colorPtr : 0x7c00;
|
||||
descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)colorPtr + 1) : 0x03e0;
|
||||
descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)colorPtr + 2) : 0x001f;
|
||||
descr.colorMap = 0;
|
||||
break;
|
||||
|
||||
case 24:
|
||||
case 32:
|
||||
descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0xff0000;
|
||||
descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x00ff00;
|
||||
descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x0000ff;
|
||||
descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *) colorPtr : 0xff0000;
|
||||
descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)colorPtr + 1) : 0x00ff00;
|
||||
descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)colorPtr + 2) : 0x0000ff;
|
||||
descr.colorMap = 0;
|
||||
break;
|
||||
|
||||
|
@ -3839,21 +3912,35 @@ INT X11DRV_GetDIBits( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, UINT startscan,
|
|||
PALETTEENTRY palette[256];
|
||||
BITMAPOBJ *bmp;
|
||||
int height;
|
||||
LONG tempHeight;
|
||||
int bitmap_type;
|
||||
BOOL core_header;
|
||||
void* colorPtr;
|
||||
|
||||
GetPaletteEntries( GetCurrentObject( physDev->hdc, OBJ_PAL ), 0, 256, palette );
|
||||
|
||||
if (!(bmp = (BITMAPOBJ *) GDI_GetObjPtr( hbitmap, BITMAP_MAGIC ))) return 0;
|
||||
|
||||
dib = (X11DRV_DIBSECTION *) bmp->dib;
|
||||
|
||||
bitmap_type = DIB_GetBitmapInfo( (BITMAPINFOHEADER*) info, &descr.infoWidth, &tempHeight, &descr.infoBpp, &descr.compression);
|
||||
descr.lines = tempHeight;
|
||||
if (bitmap_type == -1)
|
||||
{
|
||||
ERR("Invalid bitmap\n");
|
||||
lines = 0;
|
||||
goto done;
|
||||
}
|
||||
core_header = (bitmap_type == 0);
|
||||
colorPtr = (LPBYTE) info + (WORD) info->bmiHeader.biSize;
|
||||
|
||||
TRACE("%u scanlines of (%i,%i) -> (%i,%i) starting from %u\n",
|
||||
lines, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight,
|
||||
(int)info->bmiHeader.biWidth, (int)info->bmiHeader.biHeight,
|
||||
startscan );
|
||||
(int)descr.infoWidth, descr.lines, startscan);
|
||||
|
||||
if( lines > bmp->bitmap.bmHeight ) lines = bmp->bitmap.bmHeight;
|
||||
|
||||
height = info->bmiHeader.biHeight;
|
||||
height = descr.lines;
|
||||
if (height < 0) height = -height;
|
||||
if( lines > height ) lines = height;
|
||||
/* Top-down images have a negative biHeight, the scanlines of theses images
|
||||
|
@ -3862,7 +3949,7 @@ INT X11DRV_GetDIBits( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, UINT startscan,
|
|||
* (the number of scan lines to copy).
|
||||
* Negative lines are correctly handled by X11DRV_DIB_GetImageBits_xx.
|
||||
*/
|
||||
if( info->bmiHeader.biHeight < 0 && lines > 0) lines = -lines;
|
||||
if( descr.lines < 0 && lines > 0) lines = -lines;
|
||||
|
||||
if( startscan >= bmp->bitmap.bmHeight )
|
||||
{
|
||||
|
@ -3870,13 +3957,6 @@ INT X11DRV_GetDIBits( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, UINT startscan,
|
|||
goto done;
|
||||
}
|
||||
|
||||
if (DIB_GetBitmapInfo( &info->bmiHeader, &descr.infoWidth, &descr.lines,
|
||||
&descr.infoBpp, &descr.compression ) == -1)
|
||||
{
|
||||
lines = 0;
|
||||
goto done;
|
||||
}
|
||||
|
||||
descr.colorMap = NULL;
|
||||
|
||||
switch (descr.infoBpp)
|
||||
|
@ -3886,12 +3966,12 @@ INT X11DRV_GetDIBits( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, UINT startscan,
|
|||
case 8:
|
||||
descr.rMask= descr.gMask = descr.bMask = 0;
|
||||
if(coloruse == DIB_RGB_COLORS)
|
||||
descr.colorMap = info->bmiColors;
|
||||
descr.colorMap = colorPtr;
|
||||
else {
|
||||
int num_colors = 1 << descr.infoBpp, i;
|
||||
RGBQUAD *rgb;
|
||||
COLORREF colref;
|
||||
WORD *index = (WORD*)info->bmiColors;
|
||||
WORD *index = (WORD*)colorPtr;
|
||||
descr.colorMap = rgb = HeapAlloc(GetProcessHeap(), 0, num_colors * sizeof(RGBQUAD));
|
||||
for(i = 0; i < num_colors; i++, rgb++, index++) {
|
||||
colref = X11DRV_PALETTE_ToLogical(X11DRV_PALETTE_ToPhysical(physDev, PALETTEINDEX(*index)));
|
||||
|
@ -3904,15 +3984,15 @@ INT X11DRV_GetDIBits( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, UINT startscan,
|
|||
break;
|
||||
case 15:
|
||||
case 16:
|
||||
descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0x7c00;
|
||||
descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x03e0;
|
||||
descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x001f;
|
||||
descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *) colorPtr : 0x7c00;
|
||||
descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)colorPtr + 1) : 0x03e0;
|
||||
descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)colorPtr + 2) : 0x001f;
|
||||
break;
|
||||
case 24:
|
||||
case 32:
|
||||
descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *)info->bmiColors : 0xff0000;
|
||||
descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 1) : 0x00ff00;
|
||||
descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)info->bmiColors + 2) : 0x0000ff;
|
||||
descr.rMask = (descr.compression == BI_BITFIELDS) ? *(DWORD *) colorPtr : 0xff0000;
|
||||
descr.gMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)colorPtr + 1) : 0x00ff00;
|
||||
descr.bMask = (descr.compression == BI_BITFIELDS) ? *((DWORD *)colorPtr + 2) : 0x0000ff;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -3929,7 +4009,7 @@ INT X11DRV_GetDIBits( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, UINT startscan,
|
|||
descr.xDest = 0;
|
||||
descr.yDest = 0;
|
||||
descr.xSrc = 0;
|
||||
descr.sizeImage = info->bmiHeader.biSizeImage;
|
||||
descr.sizeImage = core_header ? 0 : info->bmiHeader.biSizeImage;
|
||||
|
||||
if (descr.lines > 0)
|
||||
{
|
||||
|
@ -3951,25 +4031,25 @@ INT X11DRV_GetDIBits( X11DRV_PDEVICE *physDev, HBITMAP hbitmap, UINT startscan,
|
|||
X11DRV_DIB_GetImageBits( &descr );
|
||||
X11DRV_DIB_Unlock(bmp, TRUE);
|
||||
|
||||
if(info->bmiHeader.biSizeImage == 0) /* Fill in biSizeImage */
|
||||
info->bmiHeader.biSizeImage = X11DRV_DIB_GetDIBWidthBytes( info->bmiHeader.biWidth,
|
||||
info->bmiHeader.biBitCount )
|
||||
* abs( info->bmiHeader.biHeight );
|
||||
if(!core_header && info->bmiHeader.biSizeImage == 0) /* Fill in biSizeImage */
|
||||
info->bmiHeader.biSizeImage = X11DRV_DIB_GetDIBImageBytes( descr.infoWidth,
|
||||
descr.lines,
|
||||
descr.infoBpp);
|
||||
|
||||
if (descr.compression == BI_BITFIELDS)
|
||||
{
|
||||
*(DWORD *)info->bmiColors = descr.rMask;
|
||||
*((DWORD *)info->bmiColors+1) = descr.gMask;
|
||||
*((DWORD *)info->bmiColors+2) = descr.bMask;
|
||||
*(DWORD *) colorPtr = descr.rMask;
|
||||
*((DWORD *)colorPtr + 1) = descr.gMask;
|
||||
*((DWORD *)colorPtr + 2) = descr.bMask;
|
||||
}
|
||||
else
|
||||
else if (!core_header)
|
||||
{
|
||||
/* if RLE or JPEG compression were supported,
|
||||
* this line would be invalid. */
|
||||
info->bmiHeader.biCompression = 0;
|
||||
}
|
||||
|
||||
if(descr.colorMap && descr.colorMap != info->bmiColors)
|
||||
if(descr.colorMap && descr.colorMap != colorPtr)
|
||||
HeapFree(GetProcessHeap(), 0, descr.colorMap);
|
||||
done:
|
||||
GDI_ReleaseObj( hbitmap );
|
||||
|
@ -4014,7 +4094,7 @@ static void X11DRV_DIB_DoCopyDIBSection(BITMAPOBJ *bmp, BOOL toDIB,
|
|||
X11DRV_DIB_IMAGEBITS_DESCR descr;
|
||||
int identity[2] = {0,1};
|
||||
|
||||
if (DIB_GetBitmapInfo( &dib->dibSection.dsBmih, &descr.infoWidth, &descr.lines,
|
||||
if (DIB_GetBitmapInfo( &dib->dibSection.dsBmih, &descr.infoWidth, (DWORD*) &descr.lines,
|
||||
&descr.infoBpp, &descr.compression ) == -1)
|
||||
return;
|
||||
|
||||
|
@ -4596,29 +4676,43 @@ HBITMAP X11DRV_DIB_CreateDIBSection(
|
|||
int nColorMap;
|
||||
RGBQUAD *colorTable = NULL;
|
||||
|
||||
/* Fill BITMAP32 structure with DIB data */
|
||||
const BITMAPINFOHEADER *bi = &bmi->bmiHeader;
|
||||
/* Fill BITMAP structure with DIB data */
|
||||
INT effHeight, totalSize;
|
||||
BITMAP bm;
|
||||
LPVOID mapBits = NULL;
|
||||
|
||||
TRACE("format (%ld,%ld), planes %d, bpp %d, size %ld, colors %ld (%s)\n",
|
||||
bi->biWidth, bi->biHeight, bi->biPlanes, bi->biBitCount,
|
||||
bi->biSizeImage, bi->biClrUsed, usage == DIB_PAL_COLORS? "PAL" : "RGB");
|
||||
int bitmap_type;
|
||||
BOOL core_header;
|
||||
LONG width, height;
|
||||
WORD planes, bpp, compression;
|
||||
DWORD sizeImage;
|
||||
void* colorPtr;
|
||||
|
||||
effHeight = bi->biHeight >= 0 ? bi->biHeight : -bi->biHeight;
|
||||
if (((bitmap_type = DIB_GetBitmapInfoEx((BITMAPINFOHEADER*) bmi,
|
||||
&width, &height, &planes, &bpp, &compression, &sizeImage)) == -1))
|
||||
{
|
||||
ERR("Invalid bitmap\n");
|
||||
return 0;
|
||||
}
|
||||
core_header = (bitmap_type == 0);
|
||||
|
||||
TRACE("format (%ld,%ld), planes %d, bpp %d, size %ld, %s\n",
|
||||
width, height, planes, bpp,
|
||||
sizeImage, usage == DIB_PAL_COLORS? "PAL" : "RGB");
|
||||
|
||||
effHeight = height >= 0 ? height : -height;
|
||||
bm.bmType = 0;
|
||||
bm.bmWidth = bi->biWidth;
|
||||
bm.bmWidth = width;
|
||||
bm.bmHeight = effHeight;
|
||||
bm.bmWidthBytes = ovr_pitch ? ovr_pitch : X11DRV_DIB_GetDIBWidthBytes(bm.bmWidth, bi->biBitCount);
|
||||
bm.bmPlanes = bi->biPlanes;
|
||||
bm.bmBitsPixel = bi->biBitCount;
|
||||
bm.bmWidthBytes = ovr_pitch ? ovr_pitch : X11DRV_DIB_GetDIBWidthBytes(bm.bmWidth, bpp);
|
||||
bm.bmPlanes = planes;
|
||||
bm.bmBitsPixel = bpp;
|
||||
bm.bmBits = NULL;
|
||||
|
||||
/* Get storage location for DIB bits. Only use biSizeImage if it's valid and
|
||||
/* Get storage location for DIB bits. Only use sizeImage if it's valid and
|
||||
we're dealing with a compressed bitmap. Otherwise, use width * height. */
|
||||
if (bi->biSizeImage && (bi->biCompression == BI_RLE4 || bi->biCompression == BI_RLE8))
|
||||
totalSize = bi->biSizeImage;
|
||||
if (sizeImage && (compression == BI_RLE4 || compression == BI_RLE8))
|
||||
totalSize = sizeImage;
|
||||
else
|
||||
totalSize = bm.bmWidthBytes * effHeight;
|
||||
|
||||
|
@ -4658,28 +4752,47 @@ HBITMAP X11DRV_DIB_CreateDIBSection(
|
|||
if (dib)
|
||||
{
|
||||
dib->dibSection.dsBm = bm;
|
||||
dib->dibSection.dsBmih = *bi;
|
||||
|
||||
if (core_header)
|
||||
{
|
||||
/* Convert the BITMAPCOREHEADER to a BITMAPINFOHEADER.
|
||||
The structure is already filled with zeros */
|
||||
dib->dibSection.dsBmih.biSize = sizeof(BITMAPINFOHEADER);
|
||||
dib->dibSection.dsBmih.biWidth = width;
|
||||
dib->dibSection.dsBmih.biHeight = height;
|
||||
dib->dibSection.dsBmih.biPlanes = planes;
|
||||
dib->dibSection.dsBmih.biBitCount = bpp;
|
||||
dib->dibSection.dsBmih.biCompression = compression;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Truncate extended bitmap headers (BITMAPV4HEADER etc.) */
|
||||
dib->dibSection.dsBmih = *((BITMAPINFOHEADER*) bmi);
|
||||
dib->dibSection.dsBmih.biSize = sizeof(BITMAPINFOHEADER);
|
||||
}
|
||||
|
||||
dib->dibSection.dsBmih.biSizeImage = totalSize;
|
||||
colorPtr = (LPBYTE) bmi + (WORD) bmi->bmiHeader.biSize;
|
||||
|
||||
/* Set dsBitfields values */
|
||||
if ( usage == DIB_PAL_COLORS || bi->biBitCount <= 8)
|
||||
if ( usage == DIB_PAL_COLORS || bpp <= 8)
|
||||
{
|
||||
dib->dibSection.dsBitfields[0] = dib->dibSection.dsBitfields[1] = dib->dibSection.dsBitfields[2] = 0;
|
||||
}
|
||||
else switch( bi->biBitCount )
|
||||
else switch( bpp )
|
||||
{
|
||||
case 15:
|
||||
case 16:
|
||||
dib->dibSection.dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)bmi->bmiColors : 0x7c00;
|
||||
dib->dibSection.dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 1) : 0x03e0;
|
||||
dib->dibSection.dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 2) : 0x001f;
|
||||
dib->dibSection.dsBitfields[0] = (compression == BI_BITFIELDS) ? *(DWORD *) colorPtr : 0x7c00;
|
||||
dib->dibSection.dsBitfields[1] = (compression == BI_BITFIELDS) ? *((DWORD *)colorPtr + 1) : 0x03e0;
|
||||
dib->dibSection.dsBitfields[2] = (compression == BI_BITFIELDS) ? *((DWORD *)colorPtr + 2) : 0x001f;
|
||||
break;
|
||||
|
||||
case 24:
|
||||
case 32:
|
||||
dib->dibSection.dsBitfields[0] = (bi->biCompression == BI_BITFIELDS) ? *(DWORD *)bmi->bmiColors : 0xff0000;
|
||||
dib->dibSection.dsBitfields[1] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 1) : 0x00ff00;
|
||||
dib->dibSection.dsBitfields[2] = (bi->biCompression == BI_BITFIELDS) ? *((DWORD *)bmi->bmiColors + 2) : 0x0000ff;
|
||||
dib->dibSection.dsBitfields[0] = (compression == BI_BITFIELDS) ? *(DWORD *) colorPtr : 0xff0000;
|
||||
dib->dibSection.dsBitfields[1] = (compression == BI_BITFIELDS) ? *((DWORD *)colorPtr + 1) : 0x00ff00;
|
||||
dib->dibSection.dsBitfields[2] = (compression == BI_BITFIELDS) ? *((DWORD *)colorPtr + 2) : 0x0000ff;
|
||||
break;
|
||||
}
|
||||
dib->dibSection.dshSection = section;
|
||||
|
@ -4694,8 +4807,8 @@ HBITMAP X11DRV_DIB_CreateDIBSection(
|
|||
/* Create Device Dependent Bitmap and add DIB pointer */
|
||||
if (dib)
|
||||
{
|
||||
int depth = (bi->biBitCount == 1) ? 1 : GetDeviceCaps(physDev->hdc, BITSPIXEL);
|
||||
res = CreateBitmap(bi->biWidth, effHeight, 1, depth, NULL);
|
||||
int depth = (bpp == 1) ? 1 : GetDeviceCaps(physDev->hdc, BITSPIXEL);
|
||||
res = CreateBitmap(width, effHeight, 1, depth, NULL);
|
||||
|
||||
if (res)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue