我正在尝试读取位图标头。我定义了以下结构:
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对字符串不起作用,我不知道为什么。除此之外,我认为这种打印反向字符串的方法是一种非常奇怪的读取值的方法。
我在这里做错了什么,这样做的正确方法是什么?提前谢谢。
更新! 原来这是一个字节序问题。但是我该怎么读呢?我只想得到一个带有文件大小(或宽度,高度,任何东西)的整数。
答案 0 :(得分:2)
答案 1 :(得分:0)
欢迎来到现实世界,不同的计算机有不同的endianness。直接读取二进制字段绝不是一个好主意,您需要知道字节序。
BMP文件格式可能有一个明确定义的字节顺序(可能是由于它的x86根源而导致的小端),你需要确保始终以正确的方式读取任何多字节字段。 / p>
更新:Wikipedia states:
所有整数值都以小端格式存储(即最低有效字节优先)。>
答案 2 :(得分:0)
以“反向”方式存储内容称为机器的 endianness 。 X86机器以 little-endian 顺序存储它们的字节。
您尝试使用将ASCII值转换为int
的函数转换十六进制值。这是工作的错误工具。
答案 3 :(得分:0)