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.
This commit is contained in:
parent
9c2dcb255e
commit
530e789d7e
|
@ -155,7 +155,96 @@ static void test_createdibitmap(void)
|
||||||
ReleaseDC(0, hdc);
|
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)
|
START_TEST(bitmap)
|
||||||
{
|
{
|
||||||
test_createdibitmap();
|
test_createdibitmap();
|
||||||
|
test_dibsections();
|
||||||
}
|
}
|
||||||
|
|
|
@ -324,7 +324,50 @@ int *X11DRV_DIB_BuildColorMap( X11DRV_PDEVICE *physDev, WORD coloruse, WORD dept
|
||||||
isInfo, colorPtr, 0, colors);
|
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
|
* X11DRV_DIB_MapColor
|
||||||
*/
|
*/
|
||||||
|
@ -3972,6 +4015,7 @@ static void X11DRV_DIB_DoCopyDIBSection(BITMAPOBJ *bmp, BOOL toDIB,
|
||||||
{
|
{
|
||||||
X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
|
X11DRV_DIBSECTION *dib = (X11DRV_DIBSECTION *) bmp->dib;
|
||||||
X11DRV_DIB_IMAGEBITS_DESCR descr;
|
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, &descr.lines,
|
||||||
&descr.infoBpp, &descr.compression ) == -1)
|
&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.bits = dib->dibSection.dsBm.bmBits;
|
||||||
descr.depth = bmp->bitmap.bmBitsPixel;
|
descr.depth = bmp->bitmap.bmBitsPixel;
|
||||||
|
|
||||||
|
if(descr.infoBpp == 1)
|
||||||
|
descr.colorMap = (void*)identity;
|
||||||
|
|
||||||
switch (descr.infoBpp)
|
switch (descr.infoBpp)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
|
@ -4550,6 +4597,7 @@ HBITMAP X11DRV_DIB_CreateDIBSection(
|
||||||
X11DRV_DIBSECTION *dib = NULL;
|
X11DRV_DIBSECTION *dib = NULL;
|
||||||
int *colorMap = NULL;
|
int *colorMap = NULL;
|
||||||
int nColorMap;
|
int nColorMap;
|
||||||
|
RGBQUAD *colorTable = NULL;
|
||||||
|
|
||||||
/* Fill BITMAP32 structure with DIB data */
|
/* Fill BITMAP32 structure with DIB data */
|
||||||
const BITMAPINFOHEADER *bi = &bmi->bmiHeader;
|
const BITMAPINFOHEADER *bi = &bmi->bmiHeader;
|
||||||
|
@ -4602,10 +4650,11 @@ HBITMAP X11DRV_DIB_CreateDIBSection(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create Color Map */
|
/* 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,
|
colorMap = X11DRV_DIB_BuildColorMap( usage == DIB_PAL_COLORS? physDev : NULL,
|
||||||
usage, bm.bmBitsPixel, bmi, &nColorMap );
|
usage, bm.bmBitsPixel, bmi, &nColorMap );
|
||||||
|
colorTable = X11DRV_DIB_BuildColorTable( physDev, usage, bm.bmBitsPixel, bmi );
|
||||||
|
}
|
||||||
/* Allocate Memory for DIB and fill structure */
|
/* Allocate Memory for DIB and fill structure */
|
||||||
if (bm.bmBits)
|
if (bm.bmBits)
|
||||||
dib = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(X11DRV_DIBSECTION));
|
dib = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(X11DRV_DIBSECTION));
|
||||||
|
@ -4642,6 +4691,7 @@ HBITMAP X11DRV_DIB_CreateDIBSection(
|
||||||
dib->status = DIB_Status_None;
|
dib->status = DIB_Status_None;
|
||||||
dib->nColorMap = nColorMap;
|
dib->nColorMap = nColorMap;
|
||||||
dib->colorMap = colorMap;
|
dib->colorMap = colorMap;
|
||||||
|
dib->colorTable = colorTable;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create Device Dependent Bitmap and add DIB pointer */
|
/* 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 (dib && dib->image) { XDestroyImage(dib->image); dib->image = NULL; }
|
||||||
if (colorMap) { HeapFree(GetProcessHeap(), 0, colorMap); colorMap = 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 (dib) { HeapFree(GetProcessHeap(), 0, dib); dib = NULL; }
|
||||||
if (bmp) { GDI_ReleaseObj(res); bmp = NULL; }
|
if (bmp) { GDI_ReleaseObj(res); bmp = NULL; }
|
||||||
if (res) { DeleteObject(res); res = 0; }
|
if (res) { DeleteObject(res); res = 0; }
|
||||||
|
@ -4740,6 +4791,8 @@ void X11DRV_DIB_DeleteDIBSection(BITMAPOBJ *bmp)
|
||||||
|
|
||||||
if (dib->colorMap)
|
if (dib->colorMap)
|
||||||
HeapFree(GetProcessHeap(), 0, dib->colorMap);
|
HeapFree(GetProcessHeap(), 0, dib->colorMap);
|
||||||
|
if (dib->colorTable)
|
||||||
|
HeapFree(GetProcessHeap(), 0, dib->colorTable);
|
||||||
|
|
||||||
DeleteCriticalSection(&(dib->lock));
|
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;
|
if (!(bmp = (BITMAPOBJ*)GDI_GetObjPtr( hBitmap, BITMAP_MAGIC ))) return 0;
|
||||||
dib = (X11DRV_DIBSECTION *) bmp->dib;
|
dib = (X11DRV_DIBSECTION *) bmp->dib;
|
||||||
|
|
||||||
if (dib && dib->colorMap) {
|
if (dib && dib->colorMap && start < dib->nColorMap) {
|
||||||
UINT end = count + start;
|
UINT end = count + start;
|
||||||
if (end > dib->nColorMap) end = dib->nColorMap;
|
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.
|
* of the bitmap object.
|
||||||
*/
|
*/
|
||||||
X11DRV_DIB_Lock(bmp, DIB_Status_AppMod, FALSE);
|
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,
|
X11DRV_DIB_GenColorMap( physDev, dib->colorMap, DIB_RGB_COLORS,
|
||||||
dib->dibSection.dsBm.bmBitsPixel,
|
dib->dibSection.dsBm.bmBitsPixel,
|
||||||
TRUE, colors, start, end );
|
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;
|
if (!(bmp = (BITMAPOBJ*)GDI_GetObjPtr( hBitmap, BITMAP_MAGIC ))) return 0;
|
||||||
dib = (X11DRV_DIBSECTION *) bmp->dib;
|
dib = (X11DRV_DIBSECTION *) bmp->dib;
|
||||||
|
|
||||||
if (dib && dib->colorMap) {
|
if (dib && dib->colorTable && start < dib->nColorMap) {
|
||||||
UINT i, end = count + start;
|
if (start + count > dib->nColorMap) count = dib->nColorMap - start;
|
||||||
if (end > dib->nColorMap) end = dib->nColorMap;
|
memcpy(colors, dib->colorTable + start, count * sizeof(RGBQUAD));
|
||||||
for (i = start; i < end; i++,colors++) {
|
ret = count;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
GDI_ReleaseObj( hBitmap );
|
GDI_ReleaseObj( hBitmap );
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -261,6 +261,10 @@ typedef struct
|
||||||
int nColorMap;
|
int nColorMap;
|
||||||
int *colorMap;
|
int *colorMap;
|
||||||
|
|
||||||
|
/* Original dib color table converted to
|
||||||
|
rgb values if usage was DIB_PAL_COLORS */
|
||||||
|
RGBQUAD *colorTable;
|
||||||
|
|
||||||
/* Cached XImage */
|
/* Cached XImage */
|
||||||
XImage *image;
|
XImage *image;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue