读取位图标题,获取反转值

时间:2012-01-25 13:45:01

标签: c bitmap

我正在尝试读取位图标头。我定义了以下结构:

typedef struct  {
    char magic[2];
    char size[4];
    char reserved[4];
    char offset[4];
    char dibbytes[4];
    char width[4];
    char height[4];
    char colorplanes[2];
    char bpp[2];
    char rawsize[4];
    char hor_res[4];
    char ver_res[4];
    char colors[4];
    char important[4];
} bmp_t;

我用这个函数打开一个位图图像:

void open(char * filename) {
    long filesize;
    char * buffer;

    FILE * file = fopen(filename, "rb");
    fseek(file, 0, SEEK_END);
    filesize = ftell(file);
    rewind(file);
    buffer = (char *) malloc(sizeof(char) * filesize);
    fread(buffer, 1, filesize, file);
    bmp_t * bmp = (bmp_t *) buffer;
    printf("Size in hex: %02x %02x %02x %02x\n", bmp->size[0], bmp->size[1], bmp->size[2], bmp->size[3]);
    fclose(file);
}

为了测试这个,我做了一个新的位图,宽度= 1000像素,高度= 3像素。 filesize是9054字节。但是,我的程序输出是:

Size in hex: 5e 23 00 00

这有点奇怪,因为0x5e23反转为0x235e,十进制为9054(正确的文件大小)。所以值反过来保存。例如,如果我制作1000x1000位图,我应该得到一个十进制的3000054的文件大小,但我得到0xf6c62d。反过来,0x2dc6f6,是3000054(再次,正确的文件大小)。

所以我想我可以反向sprintf字符串然后使用atoi将其转换为int:

sprintf(bmp->size, "%c%c%c%c", bmp->size[3], bmp->size[2], bmp->size[1], bmp->size[0]);
printf("Size reversed: %02x %02x %02x %02x\n", bmp->size[0] & 0xFF, bmp->size[1] & 0xFF, bmp->size[2] & 0xFF, bmp->size[3] & 0xFF);
int size = atoi(bmp->size);`
printf("Size: %d\n", size);

对于图像,我得到以下结果:

Size reversed: 00 00 23 5e
Size: 0

所以sprintf工作得很好,我的字符串被反转,0x235e是正确的答案。但是atoi对字符串不起作用,我不知道为什么。除此之外,我认为这种打印反向字符串的方法是一种非常奇怪的读取值的方法。

我在这里做错了什么,这样做的正确方法是什么?提前谢谢。

更新! 原来这是一个字节序问题。但是我该怎么读呢?我只想得到一个带有文件大小(或宽度,高度,任何东西)的整数。

4 个答案:

答案 0 :(得分:2)

这是因为内存中的所有内容都以相反的顺序保存,至少在小端机器上是这样(x86属于此类别)。如果您想知道为何使用小端,请查看here以获取有关字节序的详细信息和here

答案 1 :(得分:0)

欢迎来到现实世界,不同的计算机有不同的endianness。直接读取二进制字段绝不是一个好主意,您需要知道字节序。

BMP文件格式可能有一个明确定义的字节顺序(可能是由于它的x86根源而导致的小端),你需要确保始终以正确的方式读取任何多字节字段。 / p>

更新:Wikipedia states

  

所有整数值都以小端格式存储(即最低有效字节优先)。>

答案 2 :(得分:0)

以“反向”方式存储内容称为机器的 endianness 。 X86机器以 little-endian 顺序存储它们的字节。

您尝试使用将ASCII值转换为int的函数转换十六进制值。这是工作的错误工具。

答案 3 :(得分:0)

你做错了。

这称为little-endian数据。

阅读本文:

http://en.wikipedia.org/wiki/Endianness

在文件中存储数据的方法不止一种: - )