Chinaunix首页 | 论坛 | 博客
  • 博客访问: 849187
  • 博文数量: 168
  • 博客积分: 5431
  • 博客等级: 大校
  • 技术积分: 1560
  • 用 户 组: 普通用户
  • 注册时间: 2007-10-22 11:56
文章存档

2015年(2)

2014年(1)

2013年(12)

2012年(12)

2011年(15)

2010年(5)

2009年(16)

2008年(41)

2007年(64)

分类: C/C++

2007-11-01 19:24:53

读取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) |
0

上一篇:C++图像处理资源

下一篇:BMP图象格式

给主人留下些什么吧!~~