Different value of a structure on Linux and Windows

279 views Asked by At

I'm currently working on a C-project where I should hide text in an .bmp image.

Therefore I open an image and write the file header and the info header in two structures:

typedef struct _BitmapFileHeader_
{
  uint16_t bfType_;
  uint32_t bfSize_;
  uint32_t bfReserved_;
  uint32_t bfOffBits_;
}
 __attribute__((packed))
BitmapFileHeader;

typedef struct _BitmapInfoHeader_
{
  uint32_t biSize_;
  int32_t  biWidth_;
  int32_t  biHeight_;
  uint16_t biPlanes_;
  uint16_t biBitCount_;
  uint32_t biCompression_;
  uint32_t biSizeImage_;
  int32_t  biXPelsPerMeter_;
  int32_t  biYPelsPerMeter_;
  uint32_t biClrUsed_;
  uint32_t biClrImportant_;
}BitmapInfoHeader;

BitmapFileHeader* bitmap_headerdata = NULL;
BitmapInfoHeader* bitmap_infodata = NULL;

filename is defined previously

int readBitmapFile (char* filename, BitmapFileHeader** bitmap_headerdata,
           BitmapInfoHeader** bitmap_infodata, unsigned char** bitmap_colordata)
{
  FILE* bmp_file;
  bmp_file = fopen(filename, "rb");

  fseek(bmp_file, 0, SEEK_SET);  // Set File Cursor to beginning
  fread((*bitmap_headerdata), sizeof(**bitmap_headerdata), 1, bmp_file);
  fseek(bmp_file, sizeof(**bitmap_headerdata), SEEK_SET);
  fread((*bitmap_infodata), sizeof(**bitmap_infodata), 1, bmp_file);

  int checkinfo = sizeof(**bitmap_infodata);
  int checkheader = sizeof(**bitmap_headerdata);
  printf("Size of Infodata: %d\nSize of Headerdata: %d\n", checkinfo, checkheader);

  ....
}

When I open a valid Bitmap (24bit, not compressed) and I compare the values bfType_, biBitCount and biCompression to 19778,24,0 on Linux it works just fine but when I try to run it on Windows the Program stops when it compares biBitCount to 24. When I debugged the program I noticed that all the Values from "bitmap_infodata" are one line above from where they should be (when I look at it like a table). Then I compared sizeof(**bitmap_headerdata) on Linux and on Windows and noticed that it's 14 on Linux and 16 on Windows?

Shouldn't that be the same? And why does the structure bitmap_headerdata have same values on both OS but bitmap_infodata is different?

Bernhard

2

There are 2 answers

0
fibonacci On BEST ANSWER

The packed attribute is broken in mingw gcc:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52991

You might want to consider using:

#pragma pack(1)
struct BitmapFileHeader {
    ...
};
#pragma pack()

And -mno-ms-bitfields flag.

0
Klas Lindbäck On

The problem is that structs are padded differently in different environments.

There are 2 solutions to the problem.

1: Read the header field by field.

2: Remove struct padding. The syntax to do that varies. Some compilers use #PRAGMA PACK. You are using __attribute__((__packed__)) which apparantly doesn't work on both platforms.