Discussion:
Size of buffer returned by CreateDIBSection()?
(too old to reply)
Gili
2004-05-14 04:19:52 UTC
Permalink
Hi,

I am trying to understand the layout and size of the pixel data buffer
returned by CreateDIBSection(). My code executes:



BITMAPINFO bitmapInfo = {0};

bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFO);

bitmapInfo.bmiHeader.biWidth = desktopWidth;

bitmapInfo.bmiHeader.biHeight = desktopHeight;

bitmapInfo.bmiHeader.biPlanes = 1;

bitmapInfo.bmiHeader.biBitCount = 8*3;

bitmapInfo.bmiHeader.biCompression = BI_RGB;

bitmapInfo.bmiHeader.biSizeImage = 0;

bitmapInfo.bmiHeader.biXPelsPerMeter = 0; //?

bitmapInfo.bmiHeader.biYPelsPerMeter = 0; //?

bitmapInfo.bmiHeader.biClrUsed = 3;

bitmapInfo.bmiHeader.biClrImportant = 0;

bitmapInfo.bmiColors->rgbRed = 0;

bitmapInfo.bmiColors->rgbGreen = 0;

bitmapInfo.bmiColors->rgbBlue = 0;

bitmapInfo.bmiColors->rgbReserved = 0;

bufferedImageBitmap = CreateDIBSection(hProgmanDC, &bitmapInfo,
DIB_RGB_COLORS, (void**) &bufferedImageBitmapData, 0, 0);



Now, in the above function call, what is the size of the returned
bufferedImageBitmapData buffer? I'm expecting it to be "desktopWidth *
desktopHeight * 4" but it is not (it is less). Can anyone explain why?
Furthermore, is my BITMAPINFO initialization correct or did I misinitialize
some fields? I wasn't sure what to put in for biXPelsPerMeter and
biYPelsPerMeter and I assumed setting them to zero will work fine.

Thanks,

Gili
Louis Solomon [SteelBytes]
2004-05-14 05:29:59 UTC
Permalink
Post by Gili
bitmapInfo.bmiHeader.biBitCount = 8*3;
ie, 24bit.
Post by Gili
I'm expecting it to be "desktopWidth * desktopHeight * 4" but it is not
because your made a 3bytes per pixel (24bit) DIBSection. not 4byte / 32bit.
see my most recent post in the "Re: GetDIBits and SetDIBits" thread for more
info.
Post by Gili
Furthermore, is my BITMAPINFO initialization correct or did I
misinitialize
some fields? I wasn't sure what to put in for biXPelsPerMeter and
biYPelsPerMeter and I assumed setting them to zero will work fine.
yes. that's fine.
--
Louis Solomon
www.steelbytes.com
Mike D Sutton
2004-05-14 06:42:18 UTC
Permalink
Post by Gili
I am trying to understand the layout and size of the pixel data buffer
<code snipped>
Post by Gili
Now, in the above function call, what is the size of the returned
bufferedImageBitmapData buffer? I'm expecting it to be "desktopWidth *
desktopHeight * 4" but it is not (it is less). Can anyone explain why?
Furthermore, is my BITMAPINFO initialization correct or did I misinitialize
some fields? I wasn't sure what to put in for biXPelsPerMeter and
biYPelsPerMeter and I assumed setting them to zero will work fine.
The buffer is also DWord aligned, see this post for the formulae:
http://groups.google.co.uk/groups?selm=%23Xlf09BsDHA.3416%40tk2msftngp13.phx.gbl
Post by Gili
bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFO);
This should really be:

***
bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
***

If your CreateDIBSection() code is working fine then I'm guessing it's coming back with the correct result anyway, but you may wish
to change it to avoid ambiguity.
Hope this helps,

Mike


- Microsoft Visual Basic MVP -
E-Mail: ***@mvps.org
WWW: Http://www.mvps.org/EDais/
Gili
2004-05-16 00:23:47 UTC
Permalink
http://groups.google.co.uk/groups?selm=%23Xlf09BsDHA.3416%40tk2msftngp13.phx.gbl

I didn't understand your code, but I've made changes since posting my
code. Here is my new code:

//Each scanline stride is padded with zeros at the end to be a multiple of 4

const int pixelStride = bitmapInfo.bmiHeader.biBitCount/8;

int scanlineStride = pixelStride * desktopWidth;

//Round up to a multiple of 4

scanlineStride += scanlineStride % 4;



That is, the bits are stored BRGBRGBRG... etc and only at the end of the
scanline they are padded with zeros to make the scanline length a multiple
of 4. Is this correct?



Thanks,

Gili
Louis Solomon [SteelBytes]
2004-05-17 04:38:05 UTC
Permalink
Post by Gili
const int pixelStride = bitmapInfo.bmiHeader.biBitCount/8;
to be pedantic, you should have :

pixelStride =
(bitmapInfo.bmiHeader.biBitCount*bitmapInfo.bmiHeader.biPlanes)/8;
Post by Gili
scanlineStride += scanlineStride % 4;
I think this maths is wrong ...

try
scanlineStride += 4-(scanlineStride % 4);
or
scanlineStride = (scanlineStride+3)&(~3); // faster
--
Louis Solomon
www.steelbytes.com
Loading...