Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
I'm gho author of the DxWnd tool that tries to provide support to run old and legacy programs on modern windows environment.
A very strange game is G-Nome that, despite being able to run natively on Win7-10 systems, brings a serious problem for graphic manipulation.
The game links to ddraw, but builds every frame as a
DIB_PAL_COLORS
DIB and brings the DIB to screen using
SetDIBitsToDevice
user32 calls.
The operation is supported by
OBJ_DC
type DC on video also on 32 bit color depth video modes, but produces bad colors when applied to MEM_DC type DC.
I found this while trying to scale the DIB using a typical schema like this (variable declarations and error checking stripped for brevity):
hTempDc=CreateCompatibleDC(hdc);
hbmPic=CreateCompatibleBitmap(hdc, OrigWidth, OrigHeight);
SelectObject(hTempDc, hbmPic);
SetDIBitsToDevice(hTempDc, 0, 0, OrigWidth, OrigHeight, XSrc, YSrc, uStartScan, cScanLines, lpvBits, lpbmi, fuColorUse);
StretchBlt(hdc, XDest, YDest, dwWidth, dwHeight, hTempDc, 0, 0, OrigWidth, OrigHeight, SRCCOPY);
According to MSDN, when you output a DIB_PAL_COLORS
DIB the pixels are mapped to the "current" realized palette, but of course on a 32 bit surface and on its memory DC clone there is no palette at all, so it's no wonder that the pixel colors look all wrong.
An alternative solution could be to emulate the SetDIBitsToDevice
behaviour building a 32 bit memory DC to be then scaled at will with StretchBlt
, but again it is not documented how I could convert a 8bpp DIB_PAL_COLORS
DIB to either a 32bpp DIB_RGB_DIB
or a 32bpp DC.
I already tried in several ways, but in all cases it seems that I can't identify the correct palette to be used to convert pixel indices.
Could someone help me to interpret the 8bpp DIB_PAL_COLORS
DIB format?
–
If I understand the question correctly, you have a source image in the form of a DIB with a color table and you want to get that image onto a non-palette DC using SetDIBitsToDevice.
I haven't worked with palettes in a very long time, but, if I recall correctly, you cannot use DIB_PAL_COLORS unless the destination DC is a palette device. It seems unlikely that your memory DC is a palette device, but you can check:
GetDeviceCaps(hTempDc, RASTERCAPS) & RC_PALETTE
Assuming it's not a palette device, I think you have to use DIB_RGB_COLORS for fuColorUse. SetDIBitsToDevice will use each pixel's index to look up the corresponding RGBQUAD value in the color table. (The color table comes after the BITMAPINFOHEADER in the BITMAPINFO pointed to by lpbmi.) The RGBQUAD values are applied pixel-by-pixel to the destination device.
If you still have problems, I'd look closely at the BITMAPINFO and the color table you're providing to make sure they correctly represent the format of the pixel data and the corresponding color table.
–
–
–
–
–
Oh, I think I got the culprit: another DxWnd hooker was faking the RC_PALETTE
capability in GetDeviceCaps()
. Removing that fake capability the game no longer tries to use DIB_PAL_COLORS
format and builds more manageable DIB_RGB_COLORS
DIBs. Problem fixed, sorry for the false track and thank you for helping.
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.