Discussion:
GetObject() and BITMAP.bmBitsPixel
(too old to reply)
William
2005-02-21 08:33:37 UTC
Permalink
Hi,

Env: Windows2000 SP4, VC++ 6.00

I always get an wrong BITMAP.bmBitsPixel when geting BITMAP using
GetObject().
For example,
(1) I created 32*32, 4bit(16color) bitmap file without compression by
Windows' Painter or just by VC's IDE Resource Editor;

(2) Load it by LoadImage() from my harddiskm, or by LoadBitmap() from the
Resource;

(3)get BITMAP as follows,
BITMAP bm;
int iRet = GetObject(hBmp, sizeof(BITMAP), &bm);

Then, I got bm.bmBitsPixel = 32(WHY NOT 4?)?
And bm.bmWidthBytes = 128(WHY NOT 4)

No matter the orignal file is 8bit(256color), 16bit, or 24bit,
bm.bmBitsPixel always = 32,
and bm.bmWidthBytes = 128.

But if the orignal file is 1bit(monochrome), then bm.bmBitsPixel = 1.

Tell me why if you could.

Thanks!


William
Mike D Sutton
2005-02-21 09:11:41 UTC
Permalink
Post by William
Env: Windows2000 SP4, VC++ 6.00
I always get an wrong BITMAP.bmBitsPixel when geting BITMAP using
GetObject().
<snip>
Post by William
Tell me why if you could.
I would assume you're creating a DDB in which case the bit-depth is converted to the display bit-depth, this just makes
it more efficient to draw to the screen since no bit-depth conversion needs to be performed when rendering. If you wish
to retain the original file's depth then include the LR_CREATEDIBECTION flag in the LoadImage() call.
A simple way to detect whether you've got a DDB or DIB is to inspect the bmBits member of the BITMAP structure you get
back from GetObject(), a DDB will always have this field set to 0 where as a DIB should have a valid pointer.
Hope this helps,

Mike


- Microsoft Visual Basic MVP -
E-Mail: ***@mvps.org
WWW: Http://EDais.mvps.org/
William
2005-02-21 10:10:10 UTC
Permalink
Great! Thanks Mike.

Yes, with LR_CREATEDIBECTION, I can get DIB format BITMAP in LoadImage().

Then, can I get a DIB format BITMAP by LoadBitmap()?

BTW, it seems to me that, what you described about BITMAP.bmBits is
documented in MSDN. Is that always correct?

Thanks!

William
Post by Mike D Sutton
Post by William
Env: Windows2000 SP4, VC++ 6.00
I always get an wrong BITMAP.bmBitsPixel when geting BITMAP using
GetObject().
<snip>
Post by William
Tell me why if you could.
I would assume you're creating a DDB in which case the bit-depth is
converted to the display bit-depth, this just makes
Post by Mike D Sutton
it more efficient to draw to the screen since no bit-depth conversion
needs to be performed when rendering. If you wish
Post by Mike D Sutton
to retain the original file's depth then include the LR_CREATEDIBECTION
flag in the LoadImage() call.
Post by Mike D Sutton
A simple way to detect whether you've got a DDB or DIB is to inspect the
bmBits member of the BITMAP structure you get
Post by Mike D Sutton
back from GetObject(), a DDB will always have this field set to 0 where as
a DIB should have a valid pointer.
Post by Mike D Sutton
Hope this helps,
Mike
- Microsoft Visual Basic MVP -
WWW: Http://EDais.mvps.org/
William
2005-02-21 10:23:52 UTC
Permalink
This email just fixes the front one:

Great! Thanks Mike.

Yes, with LR_CREATEDIBECTION, I can get DIB format BITMAP in LoadImage().

Then, can I get a DIB format BITMAP by LoadBitmap()?

BTW, it seems to me that, what you described about BITMAP.bmBits is NOT
documented in MSDN. Is that always correct around all Windwos OS?

Thanks!

William
Post by Mike D Sutton
Post by William
Env: Windows2000 SP4, VC++ 6.00
I always get an wrong BITMAP.bmBitsPixel when geting BITMAP using
GetObject().
<snip>
Post by William
Tell me why if you could.
I would assume you're creating a DDB in which case the bit-depth is
converted to the display bit-depth, this just makes
Post by Mike D Sutton
it more efficient to draw to the screen since no bit-depth conversion
needs to be performed when rendering. If you wish
Post by Mike D Sutton
to retain the original file's depth then include the LR_CREATEDIBECTION
flag in the LoadImage() call.
Post by Mike D Sutton
A simple way to detect whether you've got a DDB or DIB is to inspect the
bmBits member of the BITMAP structure you get
Post by Mike D Sutton
back from GetObject(), a DDB will always have this field set to 0 where as
a DIB should have a valid pointer.
Post by Mike D Sutton
Hope this helps,
Mike
- Microsoft Visual Basic MVP -
WWW: Http://EDais.mvps.org/
Mike D Sutton
2005-02-21 12:11:29 UTC
Permalink
Post by William
Great! Thanks Mike.
Yes, with LR_CREATEDIBECTION, I can get DIB format BITMAP in LoadImage().
Then, can I get a DIB format BITMAP by LoadBitmap()?
AFAIK no, however LoadImage() supersedes LoadBitmap() so you should be able to just use that.
Post by William
BTW, it seems to me that, what you described about BITMAP.bmBits is NOT
documented in MSDN. Is that always correct around all Windwos OS?
<quote src= "http://msdn.microsoft.com/library/en-us/gdi/devcons_912s.asp" >
If hgdiobj is a handle to a bitmap created by calling CreateDIBSection, [snip] In addition, the bmBits member of the
BITMAP structure contained within the DIBSECTION will contain a pointer to the bitmap's bit values.
</quote>

Hope this helps,

Mike


- Microsoft Visual Basic MVP -
E-Mail: ***@mvps.org
WWW: Http://EDais.mvps.org/
William
2005-02-21 14:46:55 UTC
Permalink
Thanks Mike!

I found out in [MSDN].

BTW, can you tell me how to create a sample 16bit or 32bit bitmap file by
any software(NOT by programming)? I just know I can't do that with Windows'
Painter or VC++'s IDE.

William
Post by Mike D Sutton
AFAIK no, however LoadImage() supersedes LoadBitmap() so you should be able to just use that.
Post by William
BTW, it seems to me that, what you described about BITMAP.bmBits is NOT
documented in MSDN. Is that always correct around all Windwos OS?
<quote src= "http://msdn.microsoft.com/library/en-us/gdi/devcons_912s.asp"
If hgdiobj is a handle to a bitmap created by calling CreateDIBSection,
[snip] In addition, the bmBits member of the
Post by Mike D Sutton
BITMAP structure contained within the DIBSECTION will contain a pointer to
the bitmap's bit values.
Post by Mike D Sutton
</quote>
Mike D Sutton
2005-02-21 14:56:25 UTC
Permalink
Post by William
I found out in [MSDN].
BTW, can you tell me how to create a sample 16bit or 32bit bitmap file by
any software(NOT by programming)? I just know I can't do that with Windows'
Painter or VC++'s IDE.
I would use Adobe Photoshop for this, however it's a little expensive for just a test (and IIRC the demo version does
not allow saving.) You may find that JASC PaintShop Pro will allow you to do this in the demo, or perhaps even the
GIMP?
If all else fails then let me know and I can send over some sample Bitmap's at varying bit-depths.
Hope this helps,

Mike


- Microsoft Visual Basic MVP -
E-Mail: ***@mvps.org
WWW: Http://EDais.mvps.org/
William
2005-02-22 07:57:46 UTC
Permalink
Thanks Mike.

I just downloaded PaintShop Pro 9 and tried. Unfortunately, it seems to me
that only 1bit, 4bit, 8bit and 24bit files can be created by PaintShop Pro
9.

I also downloaded and installed GIMP 2.0, however there are no any windows
application under my C:\Program Files\Common Files\GTK\2.0\bin. I just don't
know what was wrong. I will try again when I have some time.

I would deeply appreciate if you could take time to send me 16bit and 32bit
sample Bitmap files. 32*32 or 48*48 size will be OK.

BTW, both 24bit and 32bit color are called as true color. I just know they
occupy the different memory sizes in a BITMAP file. 3 bytes for 24bit format
and DWORD for 32bit format although the highest byte is not used.
Anything else different between them?

William
Post by Mike D Sutton
I would use Adobe Photoshop for this, however it's a little expensive for
just a test (and IIRC the demo version does
Post by Mike D Sutton
not allow saving.) You may find that JASC PaintShop Pro will allow you to
do this in the demo, or perhaps even the
Post by Mike D Sutton
GIMP?
If all else fails then let me know and I can send over some sample
Bitmap's at varying bit-depths.
n***@rtrussell.co.uk
2005-02-22 13:44:17 UTC
Permalink
William <***@mx15.freecom.ne.jp> wrote:
: I just downloaded PaintShop Pro 9 and tried. Unfortunately, it seems to me
: that only 1bit, 4bit, 8bit and 24bit files can be created by PaintShop Pro
: 9.

As far as I am aware, although you can have 16-bit and 32-bit DIBs
there's no such thing as a 16-bit or 32-bit BMP file. I am prepared
to be corrected, but my understanding is that BMP files can only be
1, 4, 8 or 24 bits. You can always put a BITMAPFILEHEADER on a DIB
and call it a BMP file, but if it's a 16 or 32 bit DIB the file you
end up with is invalid.

Richard.
http://www.rtrussell.co.uk/
To reply by email change 'news' to my forename.
Severian
2005-02-22 21:31:59 UTC
Permalink
Post by n***@rtrussell.co.uk
: I just downloaded PaintShop Pro 9 and tried. Unfortunately, it seems to me
: that only 1bit, 4bit, 8bit and 24bit files can be created by PaintShop Pro
: 9.
As far as I am aware, although you can have 16-bit and 32-bit DIBs
there's no such thing as a 16-bit or 32-bit BMP file. I am prepared
to be corrected, but my understanding is that BMP files can only be
1, 4, 8 or 24 bits. You can always put a BITMAPFILEHEADER on a DIB
and call it a BMP file, but if it's a 16 or 32 bit DIB the file you
end up with is invalid.
There are such BMP beasts, but they are quite rare and unsupported by
most software.

They generally include a BITMAPHEADERV5 (or something like that) which
defines the masks for red, green and blue in each 16 or 32 bit pixel.

My application can read them but never writes them, since so few other
programs can read them.

--
Sev
Mike D Sutton
2005-02-23 01:36:44 UTC
Permalink
Post by William
I just downloaded PaintShop Pro 9 and tried. Unfortunately, it seems to me
that only 1bit, 4bit, 8bit and 24bit files can be created by PaintShop Pro
9.
I also downloaded and installed GIMP 2.0, however there are no any windows
application under my C:\Program Files\Common Files\GTK\2.0\bin. I just don't
know what was wrong. I will try again when I have some time.
I would deeply appreciate if you could take time to send me 16bit and 32bit
sample Bitmap files. 32*32 or 48*48 size will be OK.
BTW, both 24bit and 32bit color are called as true color. I just know they
occupy the different memory sizes in a BITMAP file. 3 bytes for 24bit format
and DWORD for 32bit format although the highest byte is not used.
Anything else different between them?
Http://EDais.mvps.org/TempFiles/BMPTests.zip
You've got 1-BPP (Monochrome), 4-BPP, 8-BPP, 15-bpp (5:5:5), 16-bpp (5:6:5), 24-bpp, 32-bpp and 32-bpp with alpha data -
also threw in the PSD in case you want to use it to generate more later on, I'm guessing you're not interested in the
RLE compressed versions for now though.
Some of these formats are not part of the original Bitmap spec. however are supported in various applications and as
such you may find them 'in the wild', also since the GDI DIB is so similar to the .BMP file format (essentially a .BMP
file is nothing more than a DIB with a prefixed header) you'll often find these more obscure colour depths used within
the system.
Hope this helps,

Mike


- Microsoft Visual Basic MVP -
E-Mail: ***@mvps.org
WWW: Http://EDais.mvps.org/
William
2005-02-23 07:48:18 UTC
Permalink
Much thank you, Mike.

These BITMAP files are very useful to me.

I just tried them. Among them, BMP16.bmp and BMP32.bmp can not be opened by
LoadImage() although they can be opened by Windows' Paint.

Then, I opened them by binary format and found out that the value at offset
0x0E, that corresponds to BITMAPINFOHEADER.biSize, is 0x38 and not
sizeof(BITMAPINFOHEADER)= 0x28. If I try to change the value from 0x38 to
0x28, however, LoadImage() still fails.

In addition, if I call GetLastError() soon after LoadImage() returns NULL,
GetLastError() returns 0, that should mean NO ERROR.

So, how to open them by LoadImage() or any other APIs?

William
Post by Mike D Sutton
Http://EDais.mvps.org/TempFiles/BMPTests.zip
You've got 1-BPP (Monochrome), 4-BPP, 8-BPP, 15-bpp (5:5:5), 16-bpp
(5:6:5), 24-bpp, 32-bpp and 32-bpp with alpha data -
Post by Mike D Sutton
also threw in the PSD in case you want to use it to generate more later
on, I'm guessing you're not interested in the
Post by Mike D Sutton
RLE compressed versions for now though.
Some of these formats are not part of the original Bitmap spec. however
are supported in various applications and as
Post by Mike D Sutton
such you may find them 'in the wild', also since the GDI DIB is so similar
to the .BMP file format (essentially a .BMP
Post by Mike D Sutton
file is nothing more than a DIB with a prefixed header) you'll often find
these more obscure colour depths used within
Post by Mike D Sutton
the system.
Severian
2005-02-23 08:10:45 UTC
Permalink
zzOn Wed, 23 Feb 2005 16:48:18 +0900, "William"
Post by William
Much thank you, Mike.
These BITMAP files are very useful to me.
I just tried them. Among them, BMP16.bmp and BMP32.bmp can not be opened by
LoadImage() although they can be opened by Windows' Paint.
Then, I opened them by binary format and found out that the value at offset
0x0E, that corresponds to BITMAPINFOHEADER.biSize, is 0x38 and not
sizeof(BITMAPINFOHEADER)= 0x28. If I try to change the value from 0x38 to
0x28, however, LoadImage() still fails.
In addition, if I call GetLastError() soon after LoadImage() returns NULL,
GetLastError() returns 0, that should mean NO ERROR.
So, how to open them by LoadImage() or any other APIs?
There are "standard" BMP formats that cannot be loaded by standard
Win32 APIS. Windows is a big pile. (Should you need to add to that,
feel welcome.)
Post by William
William
Post by Mike D Sutton
Http://EDais.mvps.org/TempFiles/BMPTests.zip
You've got 1-BPP (Monochrome), 4-BPP, 8-BPP, 15-bpp (5:5:5), 16-bpp
(5:6:5), 24-bpp, 32-bpp and 32-bpp with alpha data -
Post by Mike D Sutton
also threw in the PSD in case you want to use it to generate more later
on, I'm guessing you're not interested in the
Post by Mike D Sutton
RLE compressed versions for now though.
Some of these formats are not part of the original Bitmap spec. however
are supported in various applications and as
Post by Mike D Sutton
such you may find them 'in the wild', also since the GDI DIB is so similar
to the .BMP file format (essentially a .BMP
Post by Mike D Sutton
file is nothing more than a DIB with a prefixed header) you'll often find
these more obscure colour depths used within
Post by Mike D Sutton
the system.
--
Sev
William
2005-02-23 08:59:56 UTC
Permalink
Yes I need.
I hope my app can deal with as many kinds of BITMAP files as Windows' Paint
can.

William
Should you need to add to that,feel welcome.)
Severian
2005-02-23 13:11:33 UTC
Permalink
On Wed, 23 Feb 2005 17:59:56 +0900, "William"
Post by William
Yes I need.
I hope my app can deal with as many kinds of BITMAP files as Windows' Paint
can.
There are valid BMP files that Paint cannot read. Don't think of Paint
as the ultimate arbiter of BMP validity!

My software converts 16 and 32-bit BMP files to 24-bit BMPs when
reading.

The alpha byte of 32-bit BMPs is not supported by any MS software;
however I honor and read it just as I do for TGA, TIF, PNG and others,
as long as the alpha bitmask is defined.

I do not write 16 or 32-bit BMPs as they are so rarely supported.

I don't yet read JPEG-compfessed BMPs, simply because I haven't seen
one yet.


--
Sev
Mike D Sutton
2005-02-23 10:51:00 UTC
Permalink
Post by William
These BITMAP files are very useful to me.
I just tried them. Among them, BMP16.bmp and BMP32.bmp can not be opened by
LoadImage() although they can be opened by Windows' Paint.
Then, I opened them by binary format and found out that the value at offset
0x0E, that corresponds to BITMAPINFOHEADER.biSize, is 0x38 and not
sizeof(BITMAPINFOHEADER)= 0x28. If I try to change the value from 0x38 to
0x28, however, LoadImage() still fails.
In addition, if I call GetLastError() soon after LoadImage() returns NULL,
GetLastError() returns 0, that should mean NO ERROR.
So, how to open them by LoadImage() or any other APIs?
A header size of 0x38 indicates that there are 4 extra DWord's appended to a standard BITMAPINFOHEADER structure, which
represent the individual channel masks for bit-fields compressed images. Bit-fields isn't technically a compression
method at all, it simply indicates which order the colour channels are in in the image data.
By reading this data in yourself, you can simply point CreateDIBSection() at the header data and it will create the
corresponding DIBSection for you.
Hope this helps,

Mike


- Microsoft Visual Basic MVP -
E-Mail: ***@mvps.org
WWW: Http://EDais.mvps.org/
William
2005-02-24 14:38:56 UTC
Permalink
Your explanations are always so clear and professional.
Thank you very much.

William
Post by Mike D Sutton
A header size of 0x38 indicates that there are 4 extra DWord's appended to
a standard BITMAPINFOHEADER structure, which
Post by Mike D Sutton
represent the individual channel masks for bit-fields compressed images.
Bit-fields isn't technically a compression
Post by Mike D Sutton
method at all, it simply indicates which order the colour channels are in in the image data.
By reading this data in yourself, you can simply point CreateDIBSection()
at the header data and it will create the
Post by Mike D Sutton
corresponding DIBSection for you.
Loading...