Confused Newbie

I

ilan.pillemer

Hi,

I am not sure if this is the right place to ask my question.
If not, can some direct me to the right place, please?

Anyways, here is the problem.
I have written a little program to write bitmaps.

But when I write the bitmap headers as understood from the
specifications I found when googling specifically the offset
to the bitmap data goes in the wrong place.

I used od -d to look at the header that I was producing and the header
of a sample bitmap file. By doing this I saw what needed to be
changed.

And I hacked the code it force things right. But it looks ugly.

I have included the code that should work and the hack.

Here are the octal dumps, note the value of 54 - ie the offset is in
the wrong place. And I cannot figure out why....

Note, I have already reduced the size of the header from 16 bytes to
the expected 14 bytes by not writing the last two bytes to the file.

octal dump of broken bitmap
[ilan@pillemer COS340A]$ od -d gasket.bmp | grep 19778 -C5
0000000 19778 0 54 36 0 0 54 40
0000020 0 1024 0 768 0 1 24 0
0000040 0 0 0 0 0 0 0 0
0000060 0 0 0 0 254 65024 0 254
0000100 65024 1 509 64768 1 509 64768 2
0000120 764 64512 2 764 64512 3 1019 64256

octal dump of bitmap formed by hack - works.
[ilan@pillemer COS340A]$ od -d gasket_hack.bmp | grep 19778 -C5
0000000 19778 0 54 36 0 54 0 40
0000020 0 1024 0 768 0 1 24 0
0000040 0 0 0 0 0 0 0 0
0000060 0 0 0 0 254 65024 0 254
0000100 65024 1 509 64768 1 509 64768 2
0000120 764 64512 2 764 64512 3 1019 64256
[ilan@pillemer COS340A]$

*Code before Hack*

typedef struct /**** BMP file header structure
****/
{
unsigned short bfType; /* Magic number for file */
unsigned int bfSize; /* Size of file */
unsigned short bfReserved1; /* Reserved */
unsigned short bfReserved2; /* ... */
unsigned int bfOffBits; /* Offset to bitmap data. */

} BITMAPFILEHEADER;

typedef struct /**** BMP file info structure
****/
{
unsigned int biSize; /* Size of info header */
int biWidth; /* Width of image */
int biHeight; /* Height of image */
unsigned short biPlanes; /* Number of color planes */
unsigned short biBitCount; /* Number of bits per pixel */
unsigned int biCompression; /* Type of compression to use */
unsigned int biSizeImage; /* Size of image data */
int biXPelsPerMeter; /* X pixels per meter */
int biYPelsPerMeter; /* Y pixels per meter */
unsigned int biClrUsed; /* Number of colors used */
unsigned int biClrImportant; /* Number of important colors */

} BITMAPINFOHEADER;

<snip>
bitfile = fopen("gasket.bmp","wb");
rc = fwrite(&header,sizeof(BITMAPFILEHEADER)-2,1,bitfile);
rc = fwrite(&info,sizeof(BITMAPINFOHEADER),1,bitfile);

====================================================================
*Hack*
====================================================================

typedef struct /**** BMP file header structure
****/
{
unsigned short bfType; /* Magic number for file */
unsigned int bfSize; /* Size of file */
unsigned short bfReserved1; /* Reserved */
unsigned short bfReserved2; /* ... */
unsigned int bfOffBits; /* Offset to bitmap data. Actually
moved to other header. */

} BITMAPFILEHEADER;

typedef struct /**** BMP file info structure
****/
{
unsigned int bfOffBeats; /* Because of some complication moved
offset to here. Ugly Hack. */
unsigned int biSize; /* Size of info header */
int biWidth; /* Width of image */
int biHeight; /* Height of image */
unsigned short biPlanes; /* Number of color planes */
unsigned short biBitCount; /* Number of bits per pixel */
unsigned int biCompression; /* Type of compression to use */
unsigned int biSizeImage; /* Size of image data */
int biXPelsPerMeter; /* X pixels per meter */
int biYPelsPerMeter; /* Y pixels per meter */
unsigned int biClrUsed; /* Number of colors used */
unsigned int biClrImportant; /* Number of important colors */

} BITMAPINFOHEADER;

<snip>
bitfile = fopen("gasket.bmp","wb");
rc = fwrite(&header,sizeof(BITMAPFILEHEADER)-6,1,bitfile);
rc = fwrite(&info,sizeof(BITMAPINFOHEADER),1,bitfile);
 
C

Chris Dollin

But when I write the bitmap headers as understood from the
specifications I found when googling specifically the offset
to the bitmap data goes in the wrong place.

I used od -d to look at the header that I was producing and the header
of a sample bitmap file. By doing this I saw what needed to be
changed.
typedef struct /**** BMP file info structure
****/
{
unsigned int biSize; /* Size of info header */
int biWidth; /* Width of image */
int biHeight; /* Height of image */
unsigned short biPlanes; /* Number of color planes */
unsigned short biBitCount; /* Number of bits per pixel */
unsigned int biCompression; /* Type of compression to use */
unsigned int biSizeImage; /* Size of image data */
int biXPelsPerMeter; /* X pixels per meter */
int biYPelsPerMeter; /* Y pixels per meter */
unsigned int biClrUsed; /* Number of colors used */
unsigned int biClrImportant; /* Number of important colors */

} BITMAPINFOHEADER;

<snip>
bitfile = fopen("gasket.bmp","wb");
rc = fwrite(&header,sizeof(BITMAPFILEHEADER)-2,1,bitfile);
rc = fwrite(&info,sizeof(BITMAPINFOHEADER),1,bitfile);

Don't do that. You're expecting the layout of your struct and the
layout of bytes in the bitmap format to correspond exactly. This
will happen only by an accident of the implementation: it requires
(a) that the compiler use no padding and (b) that your machine's
endianness -- the order that bytes appear in words -- is the same
as that specified by the bitmap file, as indeed they are not.

Write the bytes out in the correct order, as specified by the map
format. (You could assemble the bytes in a buffer and write /that/
out, but even that assumes that a C char aka byte corresponds to a
bitmap's byte. One day that might not be true ...)

It might be something like [I've quietly ignored signedness issues]

write_short( bitfile, header.bfType );
write_int( bitfile, header.bfSize );
write_int( bitfile, header.bfReserved1 );
write_short( bitfile, header.bfreserved2 );
write_int( bitfile, header.bfOffBits );
...

/* assuming 4-byte ints written big-endian */
void write_int( FILE *sink, unsigned int x )
{
putc( (x >> 24) & 0xff, sink );
putc( (x >> 16) & 0xff, sink );
putc( (x >> 8) & 0xff, sink );
putc( x & 0xff, sink );
}

...

It's probably a FAQ but I forgot to look it up.

--
Jena user conference, September 2007: http://hpl.hp.com/conferences/juc2007/
"The path to the web becomes deeper and wider." - October Project

Hewlett-Packard Limited registered no:
registered office: Cain Road, Bracknell, Berks RG12 1HN 690597 England
 
I

ilan.pillemer

Don't do that. You're expecting the layout of your struct and the
layout of bytes in the bitmap format to correspond exactly. This
will happen only by an accident of the implementation: it requires
(a) that the compiler use no padding and (b) that your machine's
endianness -- the order that bytes appear in words -- is the same
as that specified by the bitmap file, as indeed they are not.

So is that why the "54" is in wrong place.. my confusion was caused
by the war in Lilliput.

Thanks!

--ilAn
 
I

ilAn

But when I write the bitmap headers as understood from the
specifications I found when googling specifically the offset
to the bitmap data goes in the wrong place.
I usedod-d to look at the header that I was producing and the header
of a sample bitmap file. By doing this I saw what needed to be
changed.
typedef struct /**** BMP file info structure
****/
{
unsigned int biSize; /* Size of info header */
int biWidth; /* Width of image */
int biHeight; /* Height of image */
unsigned short biPlanes; /* Number of color planes */
unsigned short biBitCount; /* Number of bits per pixel */
unsigned int biCompression; /* Type of compression to use */
unsigned int biSizeImage; /* Size of image data */
int biXPelsPerMeter; /* X pixels per meter */
int biYPelsPerMeter; /* Y pixels per meter */
unsigned int biClrUsed; /* Number of colors used */
unsigned int biClrImportant; /* Number of important colors */
} BITMAPINFOHEADER;
<snip>
bitfile = fopen("gasket.bmp","wb");
rc = fwrite(&header,sizeof(BITMAPFILEHEADER)-2,1,bitfile);
rc = fwrite(&info,sizeof(BITMAPINFOHEADER),1,bitfile);

Don't do that. You're expecting the layout of your struct and the
layout of bytes in the bitmap format to correspond exactly. This
will happen only by an accident of the implementation: it requires
(a) that the compiler use no padding and (b) that your machine's
endianness -- the order that bytes appear in words -- is the same
as that specified by the bitmap file, as indeed they are not.

Write the bytes out in the correct order, as specified by the map
format. (You could assemble the bytes in a buffer and write /that/
out, but even that assumes that a C char aka byte corresponds to a
bitmap's byte. One day that might not be true ...)

It might be something like [I've quietly ignored signedness issues]

write_short( bitfile, header.bfType );
write_int( bitfile, header.bfSize );
write_int( bitfile, header.bfReserved1 );
write_short( bitfile, header.bfreserved2 );
write_int( bitfile, header.bfOffBits );
...

/* assuming 4-byte ints written big-endian */
void write_int( FILE *sink, unsigned int x )
{
putc( (x >> 24) & 0xff, sink );
putc( (x >> 16) & 0xff, sink );
putc( (x >> 8) & 0xff, sink );
putc( x & 0xff, sink );
}

...

It's probably a FAQ but I forgot to look it up.

--
Jena user conference, September 2007: http://hpl.hp.com/conferences/juc2007/
"The path to the web becomes deeper and wider." - October Project

Hewlett-Packard Limited registered no:
registered office: Cain Road, Bracknell, Berks RG12 1HN 690597 England


Actually, then endianness in my computer is exactly the same as that
specificed in the bitmap header file.

comp.programmer.unix pointed out the problem. The flaw was in the
false assumption that the padding of the struct was at the end; when
indeed it was not.

http://groups.google.co.za/group/co...st&q=bamboozled&rnum=1&hl=en#3c1a8021ddfa3e2f

Regards,
Ilan Pillemer
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,962
Messages
2,570,134
Members
46,692
Latest member
JenniferTi

Latest Threads

Top