在BMP图像中使用位深度来确定颜色table的大小是否有效?

Is it valid to use bit-depth to determine the size of the colour table in a BMP image?

我正在编写一个读取 BMP 的程序,我发现有时并不总是指定颜色映射条目(偏移量 0x002E)的数量。我选择使用位深度信息(偏移 0x001C)通过 0x1 << BitDepth.

确定地图中的颜色数量

一切似乎都运行良好,但是这样做会不会有看不见的后果?另外,省略色图条目数是否正常?

让我们看看Windows Metafile Format which defines the BMP format. I checked both v11.0 from 2013 and the latest v17.0。特别是,您似乎对 BITMAPINFOHEADER 类型的 DIB header(大小为 0x28 字节,在第 2.2.2.3 节中有描述)感兴趣。 BITMAPCOREHEADER(最原始的 BIP header)只指定颜色位深度,其他版本的 header 要么是专有扩展(BITMAPV2INFOHEADERBITMAPV3INFOHEADER, OS22XBITMAPHEADER, 等)或只是添加更多字段的扩展(BITMAPV4HEADER, BITMAPV5HEADER).

我们感兴趣的两个字段是BitCount(offset 0x1C,你所说的BitDepth)和ColorUsed(offset 0x2E),定义如下:

BitCount (2 bytes): A 16-bit unsigned integer that defines the number of bits that define each pixel and the maximum number of colors in the DIB. This value MUST be in the BitCount Enumeration (section 2.1.1.3)

[...]

ColorUsed (4 bytes): A 32-bit unsigned integer that specifies the number of indexes in the color table used by the DIB, as follows:

  • If this value is zero, the DIB uses the maximum number of colors that correspond to the BitCount value.
  • If this value is nonzero and the BitCount value is less than 16, this value specifies the number of colors used by the DIB.
  • If this value is nonzero and the BitCount value is 16 or greater, this value specifies the size of the color table used to optimize performance of the system palette.

Note: If this value is nonzero and greater than the maximum possible size of the color table based on the BitCount value, the maximum color table size SHOULD be assumed.

从这里应该清楚,一般情况下,仅仅考虑BitCount来确定颜色的大小是不够的table.

为了更详细一点,BitCount 的唯一有效值是:

typedef enum {
    BI_BITCOUNT_0 = 0x0000,
    BI_BITCOUNT_1 = 0x0001,
    BI_BITCOUNT_2 = 0x0004,
    BI_BITCOUNT_3 = 0x0008,
    BI_BITCOUNT_4 = 0x0010,
    BI_BITCOUNT_5 = 0x0018,
    BI_BITCOUNT_6 = 0x0020
} BitCount;

现在,对于 实际 颜色尺寸 table,您需要参考文档的第 2.1.1.3 部分,里面对上面的值一一进行了详细的描述,针对每种情况解释了如果需要一种颜色table,应该是什么尺寸,如何解释,以及等等。

我不打算引用文档的整个部分,因为它很长并且可以免费查看,但这里有一个摘要:

  • BitCountBI_BITCOUNT_0:没有颜色table.

  • BitCountBI_BITCOUNT_1BI_BITCOUNT_2BI_BITCOUNT_3:颜色table尺寸是1 << BitCount

  • BitCountBI_BITCOUNT_4BI_BITCOUNT_5BI_BITCOUNT_6:

    • ColorUsed == 0: 颜色 table 尺码是 1 << BitCount
    • ColorUsed != 0: 颜色 table 尺码是 min(ColorUsed, 1 << BitCount)

总之...

Everything seems to be working fine, but are there unseen consequences of doing this?

是的,有一些注意事项,仅执行 1 << BitCount 是不够的,您应该遵循规范(呃!)。

Additionally, is it normal to omit the number of colour map entries?

不确定这样做是“正常”还是“常见”形式的著名 BMP 实现,但根据规范肯定是合法的。注意:这里的“省略”我假设你的意思是将 ColorUsed 设置为 0,除非你使用的是另一种没有 ColorUsed 字段的 DIB header .