Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Finding the BITS of a DIB?

0 views
Skip to first unread message

Brian Fleming

unread,
Jan 6, 1998, 3:00:00 AM1/6/98
to

Have a quick question. I'm learning about DIBS (thanks go to John A.
Grant).

What I wanted to do was display a 256 color bitmap, which I have done.

But what I want to know about is the BITS of the bitmap. After I loaded
my bitmap, and pointed to the BITMAPINFO, I wasn't sure where
the BITS to the bitmap were. Based on a sample program,
I just assumed the bits were immediately AFTER the BITMAPINFO
strucutre and the RGBQUAD array. What I did was this.

lpBits = (LPSTR)BitmapInfo +
(WORD)BitmapInfo->bmiHeader.biSize +
sizeof(RGBQUAD) * 256; // 8-bit bitmap
using all 256 colors.

This works. But I had to take a leap of faith that the bits would be there.
Is
this how it is done for DIBS? Can I always assume the bits will
immeidately follow the BITMAPINFO data? Looking at documentation for DIBS,
it says that after
the BITMAPINFO there is an area of undefined data, THEN the BITS.

I'd appreciate any info in helping me understand this detail.

Chris Marriott

unread,
Jan 8, 1998, 3:00:00 AM1/8/98
to

In article <68us4t$10ji$1...@piglet.cc.uic.edu>, Brian Fleming
<bfle...@eecs.uic.edu> writes

A DIB on disk is exactly the same as the CF_DIB clipboard format (with,
of course a "file header" at the start). You have three items stored
immediately following on from one another:

1. The BITMAPINFO structure.
2. (Perhaps) an RGBQUAD colour palette table.
3. The bitmap "bits" data.

Chris

----------------------------------------------------------------
Chris Marriott, Microsoft Certified Solution Developer.
SkyMap Software, U.K. e-mail: ch...@skymap.com
Visit our web site at http://www.skymap.com

John A. Grant

unread,
Jan 10, 1998, 3:00:00 AM1/10/98
to

Chris Marriott wrote in message ...

I agree that the files & resources are structured as above. The
question concerns the 'hole' which may or may not appear
before the bits.

Various bits of documentation I've read indicate that the bits may
NOT be contiguous with the BITMAPINFO struct (which may
or may not include the RGBQUAD table).

Example 1:
The following appears in the FILE.C module of the DIBAPI.DLL that is
included with the WINCAP example:
"...
//If the bfOffBits field is non-zero, then the bits might *not* be
//directly following the color table in the file. Use the value in
//bfOffBits to seek the bits.
if (bmfHeader.bfOffBits != 0L)
_llseek(hFile, bmfHeader.bfOffBits, SEEK_SET)
..."

Example 2:
The following is a quote from ARTICLE.HLP from the SPRITES example:
"...
DIBs in memory
If you examine the file format structures carefully, you will see
that
the file header contains a pointer to the position of the image bits
within the file, implying that the block containing the bits need
not
be contiguous with the header. This is a convenience for the file
format but a nuisance for a memory image format ..."

Furthermore most of the other DIB reading code I've seen goes out
of its way to seek() directly to the bits, never assuming that they
immediately follow the BITMAPINFOHEADER struct.But of course,
when dealing with resource DIBs, you assume that LoadResource
gives you a handle to a contiguous block of bits. So if there is a
possibility that the bits are NOT contiguous in a *file*, why is this
not an issue for a *resource*?

The Resource Compiler strips off the BITMAPFILEHEADER,
so .bfOffBits is lost and you have no choice but to assume
that the bits are contiguous for a resource. Does RC or
LoadResource() re-align the bits (if necessary) so that they
*are* contiguous? I can't imagine either doing that. As one
other person points out, if you happen to have a DIB with
a 'hole' before the bits and you use it as a resource, you
are out of luck and it won't work.

I scanned a few hundred DIB/BMP on my disk and I couldn't
find a single file in which the bits were NOT contiguous with
the BITMAPINFOHEADER, i.e. in all cases the
BITMAPFILEHEADER.bfOffBits value was identical to:

sizeof(BITMAPINFO)+ncolour*sizeof(RGBQUAD)

where ncolour is either the default 2^n or as is contained
in BITMAPINFOHEADER.biClrUsed (or 0 for 24-bit).

I would like to see an example of a DIB that actually has
a 'hole' before the bits. I've never seen one and I don't
think they exist. Perhaps this is only for OS/2 DIBs
with BITMAPCORE<INFO HEADER>?

--
John A. Grant * I speak only for myself * (remove 'z' to reply)
Airborne Geophysics, Geological Survey of Canada, Ottawa
If you followup, please do NOT e-mail me a copy: I will read it here.

Chris Marriott

unread,
Jan 11, 1998, 3:00:00 AM1/11/98
to

In article <698poh$a2...@nrn2.NRCan.gc.ca>, "John A. Grant"
<jag...@znrcan.gc.ca> writes

>But of course,
> when dealing with resource DIBs, you assume that LoadResource
> gives you a handle to a contiguous block of bits. So if there is a
> possibility that the bits are NOT contiguous in a *file*, why is this
> not an issue for a *resource*?

I strongly suspect that this is there from "prehistoric" times. A
*resource* DIB is documented to be in CF_DIB format, where the three
items are contiguous in memory; it's difficult to imagine any situation
in which a *file* DIB would have the "hole".

Brian Fleming

unread,
Jan 11, 1998, 3:00:00 AM1/11/98
to

>I strongly suspect that this is there from "prehistoric" times. A
>*resource* DIB is documented to be in CF_DIB format, where the three
>items are contiguous in memory; it's difficult to imagine any situation
>in which a *file* DIB would have the "hole".
>
>Chris


Pretty interesting. Jeez, John (Grant), you are diligent!

What Chris said reminds me of a quick question I had. In the
BITMAPFILEHEADER, there is the bfType field.

It says that this field must have the value BM. I presumed this was a
constant, but it is not defined in the header files.

As a quick fix, I just looked up the value from some bitmap files. They
were consistent, so I just used it.

John A. Grant

unread,
Jan 11, 1998, 3:00:00 AM1/11/98
to

Brian Fleming wrote in message <69b1mu$1lvm$1...@piglet.cc.uic.edu>...

What the documentation means is "BM" (2-byte string), not
a predefined constant BM.

BITMAPFILEHEADER bf;
bf.bfType=*(WORD *)"BM"; //copies first 2 bytes

Perhaps I better clarify that. "BM" is a 'char *' pointer, so you
cast it to 'WORD *', i.e. a pointer to a WORD. Then you just
dereference the WORD * pointer to retrieve the WORD to
which it points.

You might also be able to use:
bf.bfType='BM'; //2-character constant
but I don't know how portable that syntax is.

Chris Marriott

unread,
Jan 12, 1998, 3:00:00 AM1/12/98
to

In article <69b1mu$1lvm$1...@piglet.cc.uic.edu>, Brian Fleming
<bfle...@eecs.uic.edu> writes

>What Chris said reminds me of a quick question I had. In the
>BITMAPFILEHEADER, there is the bfType field.
>
>It says that this field must have the value BM. I presumed this was a
>constant, but it is not defined in the header files.

It doesn't need to be "defined". It's literally what it says - the ASCII
value 'BM'!

Brian Fleming

unread,
Jan 12, 1998, 3:00:00 AM1/12/98
to

Ahh, ok "BM"... Very good.

I'm writing a very simple Bitmap file loader. Since I have no formal
programming experience, I'm still
learning and thinking of ways to organize my code.

With reading in a .bmp file... I figured there had to be a simple way to
read the file, so
what I did was this.

// Open the file for reading.
fpBmp = fopen(szFileName,"rb");


// Determine the size of the file.
fileSize = _GetFileSize(fpBmp);

// Alloc. mem for the entire .bmp.
Dib.ptrRawData = (char *) malloc(fileSize);

// Read the entire .bmp file into memory.
bytesRead = fread(Dib.ptrRawData,
sizeof(char),
fileSize,fpBmp);

// Point to the file header.
Dib.ptrHeader = (BITMAPFILEHEADER*) Dib.ptrRawData;

// Point to the Bitmap Info.
Dib.ptrInfo = (BITMAPINFO*) (Dib.ptrRawData +
sizeof(BITMAPFILEHEADER));

// Point to the bits.
Dib.ptrBits = (char*) ( Dib.ptrRawData +
Dib.ptrHeader->bfOffBits );

fclose(fpBmp);

I took out any error checking code and stuff. This is the basic way I
loaded the .bmp.
Kinda curious if this is an acceptable way to do it?

John A. Grant

unread,
Jan 14, 1998, 3:00:00 AM1/14/98
to

Brian Fleming wrote in message <69eol5$1r3e$1...@piglet.cc.uic.edu>...
You've got some problems...

Use GlobalAllocPtr() instead of malloc(). Eventually, you
will want to copy a DIB to the clipboard and the CF_DIB
clipboard format requires a handle to the packed DIB. Also,
if you're not aware of how the clipboard works, you should
know that once you pass the handle of your data (any type)
to the clipboard, you no longer own that handle and you're
not supposed to free it.

What does _GetFileSize() do? The size of the block that you
need to allocate is:
sizeof(BITMAPINFOHEADER) +
bih.biClrUsed*sizeof(RGBQUAD) +
bih.biSizeImage

where bih is BITMAPINFO * and bih.biClrUsed has already
been fixed up by you in case it was 0 (set it to 2^n).

You seem to be allocating enough memory to hold the
BITMAPFILEHEADER, but since that isn't part of the packed
DIB (CF_DIB) format, it's 'extra'. Just read it into a local
variable and discard it. You only need to check for 'BM'
and deal with bfOffBits for prehistoric files (as discussed
already).

0 new messages