Mail Archives: djgpp/1996/08/20/10:11:25
Errors-To: postmaster AT ns1
Xref: news2.mv.net comp.os.msdos.djgpp:7653
From: Tom Wheeley <tomw AT tsys DOT demon DOT co DOT uk>
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 <stdio.h>
#include <stdlib.h>
#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
- Raw text -