From: kagel AT quasar DOT bloomberg DOT com Date: Tue, 20 Aug 1996 09:24:36 -0400 Message-Id: <9608201324.AA02684@quasar.bloomberg.com > To: tomw AT tsys DOT demon DOT co DOT uk Cc: djgpp AT delorie DOT com In-Reply-To: <840509680snz@tsys.demon.co.uk> (message from Tom Wheeley on Tue, 20 Aug 96 02:54:40 GMT) Subject: Re: strange problem reading binary files Reply-To: kagel AT dg1 DOT bloomberg DOT com Errors-To: postmaster AT ns1 Xref: news2.mv.net comp.os.msdos.djgpp:7653 From: Tom Wheeley Newsgroups: comp.os.msdos.djgpp Date: Tue, 20 Aug 96 02:54:40 GMT Organization: City Zen FM Lines: 126 Reply-To: tomw AT tsys DOT demon DOT co DOT uk X-Nntp-Posting-Host: tsys.demon.co.uk X-Newsreader: Demon Internet Simple News v1.30 X-Sig-By: Tomsystems Quote v1.2. (c)1996 Tom Wheeley, tomw AT tsys DOT demon DOT co DOT uk X-Mail2News-Path: mail-1.mail.demon.net!post.demon.co.uk!tsys.demon.co.uk Dj-Gateway: from newsgroup comp.os.msdos.djgpp Content-Type: text Content-Length: 3611 I have this extremely irrational looking bug which I cannot solve, but I am sure will be pointed out in big, embarrassing letters... Ok. Whenever I ran this program, it always reported the bmih.biSize as being 0. Clearly in a hex dump, it was 0x28: (dashes signify gaps between bits in structures below) 42 4d-3e 04 00 00-00 00-00 00-3e 00 00 00-28 00 00 00 Now, when I set it up to read just up to and including biSize, it worked fine, but whenever Iread the rest it became zero. At first, thinking it was some strange alignment thing or whatever, I rewrote it to read each element of the structures separately. (hence the READ2 and READ4 macros.) I don't think it is because I missed the size of a struct element, as all the other parts are fine. The following code should demonstrate it precisely. Defining READALL when compiling (-DREADALL) will show up the problem. I've cut out all the irrelevant bits: {bmpinfo.c} /* BMPINFO, bitmap info proggy */ #include #include #include "fbmp.h" /* can be redefined for big-endian machines */ #define READ2(x,f) (x)=getc(f);(x)|=getc(f)<<8 #define READ4(x,f) (x)=getc(f);(x)|=getc(f)<<8;(x)|=getc(f)<<16;(x)|=getc(f)<<24 Your problem is in the READ? macros. You assume that getc returns a char when it returns a 32-bit int. I think that this is causing your problem. And yes you do have an alignment problem. Try just packing your structure and fread()ing it like this: typedef struct tagBITMAPFILEHEADER { /* bmfh */ UINT bfType; DWORD bfSize __attribute__ ((packed)); UINT bfReserved1; UINT bfReserved2; DWORD bfOffBits __attribute__ ((packed)); } BITMAPFILEHEADER; typedef struct tagBITMAPINFOHEADER { /* bmih */ DWORD biSize; LONG biWidth; LONG biHeight; WORD biPlanes; WORD biBitCount; DWORD biCompression; DWORD biSImage; LONG biXPelsPerMeter; LONG biYPelsPerMeter; DWORD biClrUsed; DWORD biClrImportant; } BITMAPINFOHEADER; typedef struct A_tagBITMAPFILEHEADER { /* bmfh */ UINT bfType; DWORD bfSize __attribute__ ((packed)); UINT bfReserved1; UINT bfReserved2; DWORD bfOffBits __attribute__ ((packed)); } A_BITMAPFILEHEADER; [SNIP] int main (int argc, char *argv[]) { FILE *bmp; BITMAPFILEHEADER bmfh; A_BITMAPFILEHEADER A_bmfh; BITMAPINFOHEADER bmih; RGBQUAD bmic[1]; if(!(bmp=fopen(*++argv,"rb"))) { printf("Unable to open bmp file `%s'\n",*argv); exit(EXIT_FAILURE); } fread( &A_bmfh, sizeof A_bmfh, 1, bmp ); fread( &bmih, sizeof bmih, 1, bmp ); bmfh.bfType = A_bmfh.bfType; bmfh.bfSize = A_bmfh.bfSize; bmfh.bfReserved1 = A_bmfh.bfReserved1; bmfh.bfReserved2 = A_bmfh.bfReserved2; bmfh.bfOffBits = A_bmfh.bfOffBits; [SNIP] The use of separate packed and unpacked versions of the header structure assumes that you require maximum efficiency using the header values. If, however, the values are to be used only once or twice, and not in any loops, then you may want to eliminate the copy to the unpacked structure and just use the packed one. PORTABILITY NOTE: some CPUs, notable Motorola CPUs but others also, CANNOT perform calculations using unaligned objects; so you may want to do the copy anyway for portability sake. -- Art S. Kagel, kagel AT quasar DOT bloomberg DOT com A proverb is no proverb to you 'till life has illustrated it. -- John Keats