Reading Windows Bitmap data into an RGBA buffer.

To be able to save the image data into a TIFF tile we need the data in RGBA format. Windows provides the data in BGRA.

The following code deals with this:

    // copy result into buffer
    unsigned char *bits = Bits;
    for (uint32_t row = 0; row < (uint32_t)info.dsBm.bmHeight; ++row)
    {
        // This is windows the image is upside down.
        size_t line = (info.dsBm.bmHeight - 1) - row;
        unsigned char *pcopy_to = buffer + (line * stride);

        // Only copy stride as it may be smaller than scanline in bitmap.
        // Windows is also BGR rather than RGB
        uint8_t *pbits = bits;
        uint32_t *ptr = (uint32_t*)pcopy_to;
        uint32_t *ptrEnd = (uint32_t*)(pcopy_to + stride);
        while (ptr != ptrEnd)
        {
            *ptr = (0xff << 24) | (pbits[0] << 16) |
                     (pbits[1] << 8) | pbits[2];
            ++ptr;
            pbits += 4;
        }

        bits += info.dsBm.bmWidthBytes; // need to advance by bitmap width not buffer width
    }

Not the most elegant of code but its fast enough for what I currently need.

An extension to the above is to look for the RGB unique value set into the buffer before drawing (see previous post) ignoring the alpha value. This gets around issues when drawing rasters with masks using GDI.


Comments