C: Bitwise little-endian 混淆

C: Bitwise little-endian confusion

我正在尝试读取 BMP 文件的 header 并从中提取宽度。 我知道文件格式使用little-endian格式,所以我读了byte-per-byte,并写了这个函数到assemble an integer from 4 chars/bytes:

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。我用十六进制编辑器打开文件检查,文件没问题。

我想可能是因为我试图将一个字符移出边界,所以我将其更改为:

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

但没有解决任何问题。 希望大家帮帮我,万分感谢!

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

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

问题实际上不在班次上,因为数字 1200 的内容来自此行:

new_int += pos1;

其中 pos1 隐式转换为 int,并且由于它是带符号的 char,值为 0xB0 (1200 = 0x4B0),因此被解释为负数。显示为“下一个字节少 1”。

其他几行也有同样的问题,只是在使用1200的时候没有表现出来。这使得这个问题特别狡猾,因为你可能会看到的每个中间值都会被观察到是正确的,而错误的值是在看起来不会错的一行中创建的。从某种意义上说,这条线并没有错,只是类型错了。