Commit 530e789d authored by Huw Davies's avatar Huw Davies Committed by Alexandre Julliard

It's important to keep the original dib colour table and not just the

colour mapping associated with a dib section - it's this table that GetDIBColorTable should retrieve. Added some GetDIBColorTable tests.
parent 9c2dcb25
......@@ -155,7 +155,96 @@ static void test_createdibitmap(void)
ReleaseDC(0, hdc);
}
static void test_dibsections(void)
{
HDC hdc, hdcmem;
HBITMAP hdib, oldbm;
char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
BITMAPINFO *pbmi = (BITMAPINFO *)bmibuf;
BYTE *bits;
RGBQUAD rgb[256];
int ret;
char logpalbuf[sizeof(LOGPALETTE) + 256 * sizeof(PALETTEENTRY)];
LOGPALETTE *plogpal = (LOGPALETTE*)logpalbuf;
WORD *index;
HPALETTE hpal, oldpal;
hdc = GetDC(0);
memset(pbmi, 0, sizeof(bmibuf));
pbmi->bmiHeader.biSize = sizeof(pbmi->bmiHeader);
pbmi->bmiHeader.biHeight = 16;
pbmi->bmiHeader.biWidth = 16;
pbmi->bmiHeader.biBitCount = 1;
pbmi->bmiHeader.biPlanes = 1;
pbmi->bmiHeader.biCompression = BI_RGB;
pbmi->bmiColors[0].rgbRed = 0xff;
pbmi->bmiColors[0].rgbGreen = 0;
pbmi->bmiColors[0].rgbBlue = 0;
pbmi->bmiColors[1].rgbRed = 0;
pbmi->bmiColors[1].rgbGreen = 0;
pbmi->bmiColors[1].rgbBlue = 0xff;
hdib = CreateDIBSection(hdc, pbmi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
ok(hdib != NULL, "CreateDIBSection failed\n");
hdcmem = CreateCompatibleDC(hdc);
oldbm = SelectObject(hdcmem, hdib);
ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
ok(!memcmp(rgb, pbmi->bmiColors, 2 * sizeof(RGBQUAD)),
"GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
ret = GetDIBColorTable(hdc, 0, 2, rgb);
ok(ret == 0, "GetDIBColorTable returned %d\n", ret);
SelectObject(hdcmem, oldbm);
DeleteObject(hdib);
/* Now create a palette and a palette indexed dib section */
memset(plogpal, 0, sizeof(logpalbuf));
plogpal->palVersion = 0x300;
plogpal->palNumEntries = 2;
plogpal->palPalEntry[0].peRed = 0xff;
plogpal->palPalEntry[0].peBlue = 0xff;
plogpal->palPalEntry[1].peGreen = 0xff;
index = (WORD*)pbmi->bmiColors;
*index++ = 0;
*index = 1;
hpal = CreatePalette(plogpal);
ok(hpal != NULL, "CreatePalette failed\n");
oldpal = SelectPalette(hdc, hpal, TRUE);
hdib = CreateDIBSection(hdc, pbmi, DIB_PAL_COLORS, (void**)&bits, NULL, 0);
ok(hdib != NULL, "CreateDIBSection failed\n");
/* The colour table has already been grabbed from the dc, so we select back the
old palette */
SelectPalette(hdc, oldpal, TRUE);
oldbm = SelectObject(hdcmem, hdib);
ret = GetDIBColorTable(hdcmem, 0, 2, rgb);
ok(ret == 2, "GetDIBColorTable returned %d\n", ret);
ok(rgb[0].rgbRed == 0xff && rgb[0].rgbBlue == 0xff && rgb[0].rgbGreen == 0 &&
rgb[1].rgbRed == 0 && rgb[1].rgbBlue == 0 && rgb[1].rgbGreen == 0xff,
"GetDIBColorTable returns table 0: r%02x g%02x b%02x res%02x 1: r%02x g%02x b%02x res%02x\n",
rgb[0].rgbRed, rgb[0].rgbGreen, rgb[0].rgbBlue, rgb[0].rgbReserved,
rgb[1].rgbRed, rgb[1].rgbGreen, rgb[1].rgbBlue, rgb[1].rgbReserved);
SelectObject(hdcmem, oldbm);
DeleteObject(hdib);
DeleteDC(hdcmem);
ReleaseDC(0, hdc);
}
START_TEST(bitmap)
{
test_createdibitmap();
test_dibsections();
}
......@@ -324,7 +324,50 @@ int *X11DRV_DIB_BuildColorMap( X11DRV_PDEVICE *physDev, WORD coloruse, WORD dept
isInfo, colorPtr, 0, colors);
}
/***********************************************************************
* X11DRV_DIB_BuildColorTable
*
* Build the dib color table. This either keeps a copy of the bmiColors array if
* usage is DIB_RGB_COLORS, or looks up the palette indicies if usage is
* DIB_PAL_COLORS.
* Should not be called for a >8-bit deep bitmap.
*/
static RGBQUAD *X11DRV_DIB_BuildColorTable( X11DRV_PDEVICE *physDev, WORD coloruse, WORD depth,
const BITMAPINFO *info )
{
RGBQUAD *colorTable;
int colors, i;
colors = info->bmiHeader.biClrUsed;
if (!colors) colors = 1 << info->bmiHeader.biBitCount;
if (colors > 256) {
ERR("called with >256 colors!\n");
return NULL;
}
if (!(colorTable = HeapAlloc(GetProcessHeap(), 0, colors * sizeof(RGBQUAD) )))
return NULL;
if(coloruse == DIB_RGB_COLORS)
memcpy(colorTable, info->bmiColors, colors * sizeof(RGBQUAD));
else {
HPALETTE hpal = GetCurrentObject(physDev->hdc, OBJ_PAL);
PALETTEENTRY pal_ents[256];
WORD *index;
GetPaletteEntries(hpal, 0, 256, pal_ents);
for(i = 0, index = (WORD*)info->bmiColors; 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;
colorTable[i].rgbReserved = 0;
}
}
return colorTable;
}
/***********************************************************************
* X11DRV_DIB_MapColor
*/
......@@ -3972,6 +4015,7 @@ static void X11DRV_DIB_DoCopyDIBSection(BITMAPOBJ *bmp, BOOL toDIB,
{
X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
X11DRV_DIB_IMAGEBITS_DESCR descr;
int identity[2] = {0,1};
if (DIB_GetBitmapInfo( &dib->dibSection.dsBmih, &descr.infoWidth, &descr.lines,
&descr.infoBpp, &descr.compression ) == -1)
......@@ -3985,6 +4029,9 @@ static void X11DRV_DIB_DoCopyDIBSection(BITMAPOBJ *bmp, BOOL toDIB,
descr.bits = dib->dibSection.dsBm.bmBits;
descr.depth = bmp->bitmap.bmBitsPixel;
if(descr.infoBpp == 1)
descr.colorMap = (void*)identity;
switch (descr.infoBpp)
{
case 1:
......@@ -4550,6 +4597,7 @@ HBITMAP X11DRV_DIB_CreateDIBSection(
X11DRV_DIBSECTION *dib = NULL;
int *colorMap = NULL;
int nColorMap;
RGBQUAD *colorTable = NULL;
/* Fill BITMAP32 structure with DIB data */
const BITMAPINFOHEADER *bi = &bmi->bmiHeader;
......@@ -4602,10 +4650,11 @@ HBITMAP X11DRV_DIB_CreateDIBSection(
}
/* Create Color Map */
if (bm.bmBits && bm.bmBitsPixel <= 8)
if (bm.bmBits && bm.bmBitsPixel <= 8) {
colorMap = X11DRV_DIB_BuildColorMap( usage == DIB_PAL_COLORS? physDev : NULL,
usage, bm.bmBitsPixel, bmi, &nColorMap );
colorTable = X11DRV_DIB_BuildColorTable( physDev, usage, bm.bmBitsPixel, bmi );
}
/* Allocate Memory for DIB and fill structure */
if (bm.bmBits)
dib = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(X11DRV_DIBSECTION));
......@@ -4642,6 +4691,7 @@ HBITMAP X11DRV_DIB_CreateDIBSection(
dib->status = DIB_Status_None;
dib->nColorMap = nColorMap;
dib->colorMap = colorMap;
dib->colorTable = colorTable;
}
/* Create Device Dependent Bitmap and add DIB pointer */
......@@ -4692,6 +4742,7 @@ HBITMAP X11DRV_DIB_CreateDIBSection(
if (dib && dib->image) { XDestroyImage(dib->image); dib->image = NULL; }
if (colorMap) { HeapFree(GetProcessHeap(), 0, colorMap); colorMap = NULL; }
if (colorTable) { HeapFree(GetProcessHeap(), 0, colorTable); colorTable = NULL; }
if (dib) { HeapFree(GetProcessHeap(), 0, dib); dib = NULL; }
if (bmp) { GDI_ReleaseObj(res); bmp = NULL; }
if (res) { DeleteObject(res); res = 0; }
......@@ -4740,6 +4791,8 @@ void X11DRV_DIB_DeleteDIBSection(BITMAPOBJ *bmp)
if (dib->colorMap)
HeapFree(GetProcessHeap(), 0, dib->colorMap);
if (dib->colorTable)
HeapFree(GetProcessHeap(), 0, dib->colorTable);
DeleteCriticalSection(&(dib->lock));
}
......@@ -4757,7 +4810,7 @@ UINT X11DRV_SetDIBColorTable( X11DRV_PDEVICE *physDev, UINT start, UINT count, c
if (!(bmp = (BITMAPOBJ*)GDI_GetObjPtr( hBitmap, BITMAP_MAGIC ))) return 0;
dib = (X11DRV_DIBSECTION *) bmp->dib;
if (dib && dib->colorMap) {
if (dib && dib->colorMap && start < dib->nColorMap) {
UINT end = count + start;
if (end > dib->nColorMap) end = dib->nColorMap;
/*
......@@ -4766,6 +4819,7 @@ UINT X11DRV_SetDIBColorTable( X11DRV_PDEVICE *physDev, UINT start, UINT count, c
* of the bitmap object.
*/
X11DRV_DIB_Lock(bmp, DIB_Status_AppMod, FALSE);
memcpy(dib->colorTable + start, colors, (end - start) * sizeof(RGBQUAD));
X11DRV_DIB_GenColorMap( physDev, dib->colorMap, DIB_RGB_COLORS,
dib->dibSection.dsBm.bmBitsPixel,
TRUE, colors, start, end );
......@@ -4789,17 +4843,10 @@ UINT X11DRV_GetDIBColorTable( X11DRV_PDEVICE *physDev, UINT start, UINT count, R
if (!(bmp = (BITMAPOBJ*)GDI_GetObjPtr( hBitmap, BITMAP_MAGIC ))) return 0;
dib = (X11DRV_DIBSECTION *) bmp->dib;
if (dib && dib->colorMap) {
UINT i, end = count + start;
if (end > dib->nColorMap) end = dib->nColorMap;
for (i = start; i < end; i++,colors++) {
COLORREF col = X11DRV_PALETTE_ToLogical( dib->colorMap[i] );
colors->rgbBlue = GetBValue(col);
colors->rgbGreen = GetGValue(col);
colors->rgbRed = GetRValue(col);
colors->rgbReserved = 0;
}
ret = end-start;
if (dib && dib->colorTable && start < dib->nColorMap) {
if (start + count > dib->nColorMap) count = dib->nColorMap - start;
memcpy(colors, dib->colorTable + start, count * sizeof(RGBQUAD));
ret = count;
}
GDI_ReleaseObj( hBitmap );
return ret;
......
......@@ -261,6 +261,10 @@ typedef struct
int nColorMap;
int *colorMap;
/* Original dib color table converted to
rgb values if usage was DIB_PAL_COLORS */
RGBQUAD *colorTable;
/* Cached XImage */
XImage *image;
......
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