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);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue