dibs: keep the dib colour table
Huw D M Davies
h.davies1 at physics.ox.ac.uk
Thu Sep 16 08:41:10 CDT 2004
Huw Davies <huw at codeweavers.com>
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.
Add some GetDIBColorTable tests.
--
Huw Davies
huw at codeweavers.com
Index: dlls/x11drv/x11drv.h
===================================================================
RCS file: /home/wine/wine/dlls/x11drv/x11drv.h,v
retrieving revision 1.35
diff -u -r1.35 x11drv.h
--- dlls/x11drv/x11drv.h 9 Sep 2004 00:30:29 -0000 1.35
+++ dlls/x11drv/x11drv.h 16 Sep 2004 13:36:47 -0000
@@ -261,6 +261,10 @@
int nColorMap;
int *colorMap;
+ /* Original dib color table converted to
+ rgb values if usage was DIB_PAL_COLORS */
+ RGBQUAD *colorTable;
+
/* Cached XImage */
XImage *image;
Index: dlls/x11drv/dib.c
===================================================================
RCS file: /home/wine/wine/dlls/x11drv/dib.c,v
retrieving revision 1.16
diff -u -r1.16 dib.c
--- dlls/x11drv/dib.c 10 Sep 2004 19:35:56 -0000 1.16
+++ dlls/x11drv/dib.c 16 Sep 2004 13:36:48 -0000
@@ -324,7 +324,50 @@
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 @@
{
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 @@
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 @@
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 @@
}
/* 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 @@
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 @@
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 @@
if (dib->colorMap)
HeapFree(GetProcessHeap(), 0, dib->colorMap);
+ if (dib->colorTable)
+ HeapFree(GetProcessHeap(), 0, dib->colorTable);
DeleteCriticalSection(&(dib->lock));
}
@@ -4757,7 +4810,7 @@
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 @@
* 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 @@
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;
Index: dlls/gdi/tests/bitmap.c
===================================================================
RCS file: /home/wine/wine/dlls/gdi/tests/bitmap.c,v
retrieving revision 1.1
diff -u -r1.1 bitmap.c
--- dlls/gdi/tests/bitmap.c 13 Sep 2004 19:37:03 -0000 1.1
+++ dlls/gdi/tests/bitmap.c 16 Sep 2004 13:36:48 -0000
@@ -155,7 +155,96 @@
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();
}
More information about the wine-patches
mailing list