Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Confused Newbie

Reply
Thread Tools

Confused Newbie

 
 
ilan.pillemer@gmail.com
Guest
Posts: n/a
 
      03-28-2007
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);

 
Reply With Quote
 
 
 
 
Chris Dollin
Guest
Posts: n/a
 
      03-28-2007
http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:


> 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 >> & 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

 
Reply With Quote
 
 
 
 
ilan.pillemer@gmail.com
Guest
Posts: n/a
 
      03-28-2007
On Mar 28, 3:29 pm, Chris Dollin <(E-Mail Removed)> wrote:
> 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


 
Reply With Quote
 
ilAn
Guest
Posts: n/a
 
      03-31-2007
On Mar 28, 3:29 pm, Chris Dollin <(E-Mail Removed)> wrote:
> (E-Mail Removed) wrote:
> > 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 >> & 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/com...1a8021ddfa3e2f

Regards,
Ilan Pillemer

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Newbie confused over ICS Nuf Zed Wireless Networking 2 12-17-2005 08:09 PM
Newbie confused with custom class loader tutorial voger Java 5 09-20-2005 05:15 PM
Very New, Newbie Confused Wizard ASP .Net 1 01-03-2005 10:15 PM
Newbie: How to duplicate a webform (including code) - I'm confused. Dave Smithz ASP .Net 4 10-27-2004 06:49 PM
Confused? I certainly am (newbie) George Thompson Digital Photography 7 04-08-2004 12:15 PM



Advertisments