Windows 10 and 11 do not support top-down bitmaps like Windows 7?

Uwe Baemayr 41 Reputation points
2023-04-25T01:26:10.1633333+00:00

I have a top-down device-independent bitmap in a file and use LoadImageW() to load it and get a handle.

In Windows 7, the bitmap loaded fine. In Windows 10 and 11, loading the same bitmap returns a NULL handle, and sets the last error to zero. My understanding is that this indicates an invalid bitmap.

If I convert the bitmap file into a bottom-up bitmap, Windows 10 loads it just fine. For the record, bottom-up bitmaps are standard Windows format -- the first row of pixels in the bitmap is the bottom-most row. Top-down bitmaps are inverted, and the first row of pixels is the top-most row. This is indicated by a negative biHeight member in the BITMAPINFOHEADER structure.

As I said, LoadImageW() in Windows7 loaded both bottom-up and top-down bitmaps without any problem. Windows 10 seems to consider top-down bitmaps (which happens to be the OS/2 format but is documented by Microsoft) invalid. I can't find anything in the documentation that states top-down bitmaps are no longer supported.

I created a test Visual Studio project with a C++ program to demonstrate the problem, along with identical top-down and bottom-up bitmaps and, the first time I posted this question. I provided this via a link, but that post was deleted for "violating standards". Presumably linking isn't allowed, but there doesn't seem to be any way to provide a zip file, and I can't upload a BMP file either. I will, however, post the test program here. To reproduce the problem, just replace the bitmap with a top-down bitmap and you'll see it fails on Windows 10 and Windows 11, but works fine on Windows 7.

// TestProgram.cpp : Demonstrate that LoadImage() on windows 10
//                   fails with top-down bitmaps but Windows 7 succeeds.

#include <windows.h>
#include <tchar.h>

int main()
{
    for (int i = 0; i < 2; ++i)
    {
        const LPCWSTR psz_filename = (i == 0)
                                     ? L"bitmap-bottom-up.bmp"
                                     : L"bitmap-top-down.bmp";
        const HANDLE h_bit_map
            = LoadImage(nullptr, psz_filename, IMAGE_BITMAP, 0, 0,
                        LR_LOADFROMFILE | LR_CREATEDIBSECTION);
        if (h_bit_map == nullptr)
        {
            // An "invalid" bitmap does not call SetLastError()
            // if (GetLastError() == NO_ERROR)
            //     SetLastError(ERROR_INVALID_DATA);

            const DWORD dw_last_error = GetLastError();

            LPWSTR sz_msg_buf{};
            FormatMessage(
                FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
                nullptr, dw_last_error,
                MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                 // LPWSTR cast required (see docs)
                reinterpret_cast<LPWSTR>(&sz_msg_buf), 0, nullptr);     

            fwprintf_s(stdout, L"%s: LoadImage API call failed to return a handle;\n"
                       "\tGetLastError = %d %s\n",
                       psz_filename, dw_last_error, sz_msg_buf);
            LocalFree(sz_msg_buf);

            DeleteObject(h_bit_map);
        }
        else
            (void) fwprintf_s(stdout, L"%s: LoadImage API call succeeded!\n", psz_filename);
    }
    return (0);
}

The output on Windows 7:

.\TestProgram.exe
bitmap-bottom-up.bmp: LoadImage API call succeeded!
bitmap-top-down.bmp: LoadImage API call succeeded!

The output on Windows 10 and 11:

.\TestProgram.exe
bitmap-bottom-up.bmp: LoadImage API call succeeded!
bitmap-top-down.bmp: LoadImage API call failed to return a handle;
        GetLastError = 0 The operation completed successfully.

Note that the top-down bitmap did NOT return a handle, but also did not set the last error code. This is apparently the expected behavior when LoadImageW() is called with an invalid bitmap. I would have expected ERROR_INVALID_DATA instead. If nobody knows whether top-down bitmaps are no longer supported, I'll raise a support incident. Just seems like this would have been detected a long time ago.

Windows 10
Windows 10
A Microsoft operating system that runs on personal computers and tablets.
10,944 questions
Windows API - Win32
Windows API - Win32
A core set of Windows application programming interfaces (APIs) for desktop and server applications. Previously known as Win32 API.
2,472 questions
{count} votes

Accepted answer
  1. Xiaopo Yang - MSFT 11,746 Reputation points Microsoft Vendor
    2023-04-25T07:40:27.02+00:00

    Hello @Uwe Baemayr, reproduced and confirmed. The feedback link https://aka.ms/AAkle05 is for your reference.

    If this has an important impact on you, please open an incident via 'Contact us' tab at link below so that our engineer can work with you closely: https://developer.microsoft.com/en-us/windows/support/ and please choose the 'Technical Support - Coding/Debugging' for Windows SDK for this issue. In-addition, if the support engineer determines that the issue is the result of a bug the service request will be a no-charge case and you won't be charged.


0 additional answers

Sort by: Most helpful