www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1996/08/20/10:11:25

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


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019