Trouble with DradDibDraw and 32-bit BI_BITFIELDS images


#1

I have a trouble with DrawDibDraw function when field biCompression in
BITMAPINFOHEADER structure is equal to BI_BITFIELDS.

JUCE code:

void blitToWindow (HWND hwnd, HDC dc, const bool transparent,
                   int x, int y, const RectangleList& maskedRegion)
{
    static HDRAWDIB hdd = 0;
    static bool needToCreateDrawDib = true;

    if (needToCreateDrawDib)
    {
        needToCreateDrawDib = false;

        HDC dc = GetDC (0);
        const int n = GetDeviceCaps (dc, BITSPIXEL);
        ReleaseDC (0, dc);

        // only open if we're not palettised
        if (n > 8)
            hdd = DrawDibOpen();
    }



if (hdd == 0)
{
StretchDIBits (dc,
x, y, w, h,
0, 0, w, h,
bitmapData, (const BITMAPINFO*) &bitmapInfo,
DIB_RGB_COLORS, SRCCOPY);
}
else
{
DrawDibDraw (hdd, dc, x, y, -1, -1,
(BITMAPINFOHEADER*) &bitmapInfo, bitmapData,
0, 0, w, h, 0);
}

When using ARGB juce image.

Juce code:

WindowsBitmapImage (const PixelFormat format_,
                    const int w, const int h, const bool clearImage)
    : Image (format_, w, h)
{
    jassert (format_ == RGB || format_ == ARGB);

    pixelStride = (format_ == RGB) ? 3 : 4;

    zerostruct (bitmapInfo);
    bitmapInfo.bV4Size = sizeof (BITMAPV4HEADER);
    bitmapInfo.bV4Width = w;
    bitmapInfo.bV4Height = h;
    bitmapInfo.bV4Planes = 1;
    bitmapInfo.bV4BitCount = (unsigned short) (pixelStride * 8);

    if (format_ == ARGB)
    {
        bitmapInfo.bV4AlphaMask        = 0xff000000;
        bitmapInfo.bV4RedMask          = 0x00ff0000;
        bitmapInfo.bV4GreenMask        = 0x0000ff00;
        bitmapInfo.bV4BlueMask         = 0x000000ff;
        bitmapInfo.bV4V4Compression    = BI_BITFIELDS;
    }

No drawing if image is 32-bit BI_BITFIELDS


#2

That’s actually some of the oldest code in the whole library, and has worked solidly with no problems for probably the last 7 years, even back in the days of Windows 98! What kind of bizarre Windows setup are you using…??


#3
  • Windows 7 SP1 x64

#4

Try this code project (created from your JUCE-code).


#5

…sorry, but that’s a win32 project. Are you saying that the bitmap rendering fails when used in a juce project, or just that when you copy-and-paste my code into your own project, it doesn’t work?


#6

Hi again,

just I copy your code (from juce_win32_Windowing.cpp and )

WindowsBitmapImage (const Image::PixelFormat format_,
                    const int w, const int h, const bool clearImage)
    : Image::SharedImage (format_, w, h)

{
OutputDebugString (L"WindowsBitmapImage() constuctor\r\n");

    jassert (format_ == Image::RGB || format_ == Image::ARGB);

    pixelStride = (format_ == Image::RGB) ? 3 : 4;

    zerostruct (bitmapInfo);
    bitmapInfo.bV4Size = sizeof (BITMAPV4HEADER);
    bitmapInfo.bV4Width = w;
    bitmapInfo.bV4Height = h;
    bitmapInfo.bV4Planes = 1;
    bitmapInfo.bV4CSType = 1;
    bitmapInfo.bV4BitCount = (unsigned short) (pixelStride * 8);

    if (format_ == Image::ARGB)
    {
        bitmapInfo.bV4AlphaMask        = 0xff000000;
        bitmapInfo.bV4RedMask          = 0xff0000;
        bitmapInfo.bV4GreenMask        = 0xff00;
        bitmapInfo.bV4BlueMask         = 0xff;
        bitmapInfo.bV4V4Compression    = BI_BITFIELDS;
    }
    else
    {
        bitmapInfo.bV4V4Compression    = BI_RGB;
    }

    lineStride = -((w * pixelStride + 3) & ~3);

    HDC dc = GetDC (0);
    hdc = CreateCompatibleDC (dc);
    ReleaseDC (0, dc);

    SetMapMode (hdc, MM_TEXT);

    hBitmap = CreateDIBSection (hdc,
                                (BITMAPINFO*) &(bitmapInfo),
                                DIB_RGB_COLORS,
                                (void**) &bitmapData,
                                0, 0);

    SelectObject (hdc, hBitmap);

    if (format_ == Image::ARGB && clearImage)
        zeromem (bitmapData, abs (h * lineStride));

    imageData = bitmapData - (lineStride * (h - 1));
}

and this:
void blitToWindow (HWND hwnd, HDC dc, const bool transparent,
const int x, const int y,
const RectangleList& maskedRegion,
const uint8 updateLayeredWindowAlpha) throw()
{

    static HDRAWDIB hdd = 0;
    static bool needToCreateDrawDib = true;

    if (needToCreateDrawDib)
    {
        needToCreateDrawDib = false;

        HDC dc = GetDC (0);
        const int n = GetDeviceCaps (dc, BITSPIXEL);
        ReleaseDC (0, dc);

        // only open if we're not palettised
        if (n > 8)
            hdd = DrawDibOpen();
    }

    if (createPaletteIfNeeded)
    {
        HDC dc = GetDC (0);
        const int n = GetDeviceCaps (dc, BITSPIXEL);
        ReleaseDC (0, dc);

        if (n <= 8)
            palette = CreateHalftonePalette (dc);

        createPaletteIfNeeded = false;
    }

    if (palette != 0)
    {
        SelectPalette (dc, palette, FALSE);
        RealizePalette (dc);
        SetStretchBltMode (dc, HALFTONE);
    }

    SetMapMode (dc, MM_TEXT);

    if (transparent)
    {
        POINT p, pos;
        SIZE size;

        RECT windowBounds;
        GetWindowRect (hwnd, &windowBounds);

        p.x = -x;
        p.y = -y;
        pos.x = windowBounds.left;
        pos.y = windowBounds.top;
        size.cx = windowBounds.right - windowBounds.left;
        size.cy = windowBounds.bottom - windowBounds.top;

        BLENDFUNCTION bf;
        bf.AlphaFormat = AC_SRC_ALPHA;
        bf.BlendFlags = 0;
        bf.BlendOp = AC_SRC_OVER;
        bf.SourceConstantAlpha = updateLayeredWindowAlpha;

        if (! maskedRegion.isEmpty())
        {
            for (RectangleList::Iterator i (maskedRegion); i.next();)
            {
                const Rectangle<int>& r = *i.getRectangle();
                ExcludeClipRect (hdc, r.getX(), r.getY(), r.getRight(), r.getBottom());
            }
        }

        updateLayeredWindow (hwnd, 0, &pos, &size, hdc, &p, 0, &bf, ULW_ALPHA);
    }
    else
    {
        int savedDC = 0;

        if (! maskedRegion.isEmpty())
        {
            savedDC = SaveDC (dc);

            for (RectangleList::Iterator i (maskedRegion); i.next();)
            {
                const Rectangle<int>& r = *i.getRectangle();
                ExcludeClipRect (dc, r.getX(), r.getY(), r.getRight(), r.getBottom());
            }
        }

        if (hdd == 0)
        {
            StretchDIBits (dc,
                           x, y, width, height,
                           0, 0, width, height,
                           bitmapData, (const BITMAPINFO*) &bitmapInfo,
                           DIB_RGB_COLORS, SRCCOPY);
        }
        else
        {
            DrawDibDraw (hdd, dc, x, y, -1, -1,
                         (BITMAPINFOHEADER*) &bitmapInfo, bitmapData,
                         0, 0, width, height, 0);
        }

        if (! maskedRegion.isEmpty())
            RestoreDC (dc, savedDC);
    }
}

In juce project juce examples works, but I think in juce-examples used 24bpp bitmaps (image format Image::RGB).

When I try to copy-pasted youк code in my project, only work 24изз-images (Image::RGB) and 32изз images (juce format Image::ARGB) does not work.

DrawDibDraw returns FALSE and nothing to draw.

When I change code for bitmap creation with BI_RGB and 32bpp, juce code with DrawDibDraw work fine.


#7

I don’t publish my code so that people can copy-and-paste chunks of it into some other program (presumably ignoring my copyright and the GPL in doing so), and then ask me for help with it! This isn’t a juce question, so please keep it off the juce forum.