读取bmp格式文件头信息的问题
简单的读取方法如下(如果不是很了解bmp文件的格式可以看我在这个专栏转载的一篇文章):
/*
* This is the basic data struct for bitmap picture
*/
#ifndef HAVE_BMP_STRUCT_H
#define HAVE_BMP_STRUCT_H 1
#ifdef __cplusplus__
using namespace std;
extern "C"{
#endif
struct cBmpFileHeader{
unsigned short bfType; //"BM":bitmap file
unsigned int bfSize; //file size
unsigned short bfReserved0; //need to be 0
unsigned short bfReserved1; //need to be 0
unsigned int bfOffBits; //offset to bitmap data
}__attribute((packed));
struct cBmpInfoHeader{
unsigned int biSize; //the struct size
unsigned int biWidth; //width of image
unsigned int biHeight; //height of image
unsigned short biPlanes; //need to be 0, number of planes of the device
unsigned short biBitCount; //bits per pixel
unsigned int biCompression; //type of compression set 0 if no
unsigned int biSizeImage; //if no compression set 0 or the size of the image data
unsigned int biXpelsPerMeter; //the horizonal pixels per meter on the designated device, usally set 0;
unsigned int biYpelsPerMeter; //
unsigned int biClrUsed; //the number of colors used in the bitmap, if set 0, caculate it from biCount
unsigned int biClrImportant; //the nubmer of colors which are important, if set 0 all are
}__attribute((packed));
struct RgbQuad{
unsigned char rgbBlue;
unsigned char rgbGreen;
unsigned char rgbRed;
unsigned char rgbReserved;
}__attribute((packed));
struct cBmpHeader{
struct cBmpFileHeader file_header;
struct cBmpInfoHeader info_header;
}__attribute((packed));
#ifdef __cplusplus__
} //extern "C"{
#endif
#endif //HAVE_BMP_STRUCT_H
#include
#include
#include "../include/macros.h"
#include "../include/bmpstruct.h"
//#define BMP_FILE_PATH "./"
//using namespace std;
using namespace std;
int
main()
{
char path[50];
fscanf(stdin, "%s", path);
DEBUG("path is %s\n", path);
FILE* bmp_fp;
bmp_fp = fopen(path, "r");
if(bmp_fp == NULL){
DEBUG("fopen %s failed\n", path);
return -1;
}
struct cBmpFileHeader file_header;
struct cBmpInfoHeader info_header;
struct cBmpHeader bmp_header;
memset(&file_header, 0, sizeof(file_header));
memset(&info_header, 0, sizeof(info_header));
memset(&bmp_header, 0, sizeof(bmp_header));
if(fread(&bmp_header, 1, sizeof(bmp_header), bmp_fp) != sizeof(bmp_header)){
DEBUG("fread error!\n");
fclose(bmp_fp);
}
DEBUG("file type is %d %p\n file size is %d %p\n file reserved is %d %p %d %p\n file offset to the data is %d %p\n", bmp_header.file_header.bfType,&bmp_header.file_header.bfType, bmp_header.file_header.bfSize,&bmp_header.file_header.bfSize,bmp_header.file_header.bfReserved0,&bmp_header.file_header.bfReserved0, bmp_header.file_header.bfReserved1,&bmp_header.file_header.bfReserved1, bmp_header.file_header.bfOffBits,&bmp_header.file_header.bfOffBits);
DEBUG("biSize:%d\nbiWidth:%d\nbiHeight:%d\nbiPlanes:%d\nbiBitCOunt:%d\nbiCompression:%d\nbiSizeImage:%d\nbiXpelsPerMeter:%d\nbiYpelsPerMeter:%d\nbiClrUsed:%d\nbiClrImportant:%d\n", bmp_header.info_header.biSize, bmp_header.info_header.biWidth, bmp_header.info_header.biHeight, bmp_header.info_header.biPlanes, bmp_header.info_header.biBitCount,bmp_header.info_header.biCompression, bmp_header.info_header.biSizeImage, bmp_header.info_header.biXpelsPerMeter, bmp_header.info_header.biYpelsPerMeter, bmp_header.info_header.biClrUsed, bmp_header.info_header.biClrImportant);
fclose(bmp_fp);
}
注意的问题:
1)GNU C/C++默认情况下会主动进行必要的优化动作,这些动作会对一些特殊的应用程序造成极大的影响。这里就是其中的一种情况。
在此,需要在定义struct cBmpFileHeader,struct cBmpInfoHeader,
等数据结构的时候明确告诉编译器你不需要它进行对其操作也就是必须进行packed的操作(对于嵌入式程序最好进行align操作,
这样可以节约CPU时间,尽管浪费一点存储空降)方法:
__attribute((packed));(必须有双括号,多了也是不行的)
对齐的方法:
__attribute((align(n)));(n是对齐的字节边界)
2)由于不同的编译平台一定要注意数据类型字长的差别。
3)对于直接对二进制文件的操作,不要使用过于高级的数据类型(类如数组),否则会出莫名其妙的问题。
阅读(2765) | 评论(0) | 转发(0) |