C语言保存位图文件时的一个问题(.bmp文件)

来源:互联网 发布:网络劫持修复 编辑:程序博客网 时间:2024/05/03 14:50

http://hi.baidu.com/yanghao86/item/310c2359f227cfccd48bacb2

位图文件大概可以分为四个部分:bmp文件头(BITMAPFILEHEADER),位图信息头(BITMAPINFOHEADER),调色板和位图数据。我在用C语言保存一个位图文件的时候,发现保存的文件是错误的,无法正常打开,最后查找发现竟然是因为结构体的内存对齐造成的。

 

typedef struct tagBITMAPFILEHEADER { 
  WORD    bfType; 
  DWORD   bfSize; 
  WORD    bfReserved1; 
  WORD    bfReserved2; 
  DWORD   bfOffBits; 
} BITMAPFILEHEADER, *PBITMAPFILEHEADER;

 

上面就是BITMAPFILEHEADER在MSDN中的定义(C语言中WORD为unsigned short,DWORD为unsigned long),可以看出第一个成员bfType为占用2字节,第二个成员bfSize占用4字节,问题来了,根据内存对齐规则,如果编译器的默认对齐模数(或者通过#pragma pack设置的对齐模数)大于或等于4,则第二个成员bfSize将从字节偏移为4的地方开始存放,而第一个成员bfType只有两字节,这样在第一个成员和第二个成员之间将会出现两个没有用的填充字节,同时整个结构体的大小也将是16字节。

如果将这个BITMAPFILEHEADER结构体直接写入文件当中,显然是不符合bmp文件的格式的,自然也就无法正常打开了,解决办法是在定义结构体之前通过#pragma pack将对齐模数设为2或1,根据内存对齐规则,BITMAPFILEHEADER结构体中就不会再出现填充字节了,结构体的大小也将变为正常的14字节;当然为了不影响程序中别的部分,在结构体定义完之后,最好用#pragma pack()取消设置的对齐模数。

如果不想用这种方法,在写入文件时,就不能直接写入整个结构体,只能将结构体的成员依次写入。


原创粉丝点击