C:Bitwise little-endian混淆

时间:2015-02-07 11:35:07

标签: c bitmap bitwise-operators bmp endianness

我正在尝试读取BMP文件的标头并从中提取宽度。 我知道文件格式使用little-endian格式,所以我每字节读取一次,并编写这个函数来组合4个字符/字节的整数:

int assembleInt(char pos1, char pos2, char pos3, char pos4)
{
  new_int = 0;
  new_int += (pos4 << 24);
  new_int += (pos3 << 16);
  new_int += (pos2 << 8);
  new_int += pos1;
  return new_int;
}

对我来说,这看起来应该有效。 如果我读取位图的宽度为1200 * 1200,我得到944.我已经在十六进制编辑器中打开文件进行检查,文件没问题。

我想也许是因为我试图将一个char移出界限,所以我把它改成了这个:

int shifter = 0;
new_int += (shifter + pos4) << 24;

但它没有解决任何问题。 我希望你能帮助我,非常感谢!

2 个答案:

答案 0 :(得分:1)

BITMAPFILEHEADER没有宽度信息。 BITMAPINFOHEADER在biWidth字段中具有宽度,这是32位长的Intel-endianness(little-endian)。 BITMAPINFOHEADER位于DIB的开头,直接位于BITMAPFILEHEADER之后。您可以按以下方式访问它:

char *pDIB;  // the bitmap
width= ((LPBITMAPINFOHEADER)pDIB)->biWidth;

答案 1 :(得分:1)

这个问题实际上并没有发生变化,因为1200这个问题来自于这一行:

new_int += pos1;

pos1隐式转换为int,因为它是带符号char且值为0xB0(1200 = 0x4B0),所以它被解释为负数。在下一个字节中显示为&#34; 1#34;。

其他行具有相同的问题,但在使用值1200时不表示。这使得这个问题特别狡猾,因为您可能会看到的每个中间值都是正确的,而错误的值是在看起来不错的行中创建的。并且在某种程度上,这条线路并不是真的错了,这种类型是错误的。