...ing logging 4.0

はてなブログに移行しました。D言語の話とかいろいろ。

BITMAPINFOから画像データ全体のバイナリ列を得る

かなり手こずったので結果だけ置いておきます。

ubyte[] getBitmapBuffer(BITMAPINFO* pbi)
{
    assert(pbi);
    const uint bitsPerPixel = pbi.bmiHeader.biPlanes * pbi.bmiHeader.biBitCount;
    const uint colorMaskBytes = {
        if (pbi.bmiHeader.biCompression == BI_BITFIELDS)
            return 4 * 3; // 4 bytes * 3 masks(R,G,B)
        else
            return 0;
    }();
    const uint numPallet = {
        if (bitsPerPixel <= 8) // 1, 4, 8 bits color
        {
            if (pbi.bmiHeader.biClrUsed == 0)
                return 2 ^^ bitsPerPixel;
            else
                return pbi.bmiHeader.biClrUsed;
        }
        else if (bitsPerPixel <= 32) // 16, 24, 32 bits color
            return pbi.bmiHeader.biClrUsed;
        else
            throw new Exception("Illegal color bits bitmap");
    }();
    const uint widthBytes = (pbi.bmiHeader.biWidth * bitsPerPixel + 31) / 32 * 4;
    const uint pixelBufSize = widthBytes * pbi.bmiHeader.biHeight;
    return (cast(ubyte*)pbi)[0 .. BITMAPINFOHEADER.sizeof + colorMaskBytes + RGBQUAD.sizeof * numPallet + pixelBufSize];
}