Microsoft的位图压缩文档,特别是BI_RLE8的描述(使用运行长度编码压缩的8位索引颜色)包括以下描述:
>在绝对模式下,第一个字节为零,第二个字节是03h至FFH范围内的值。第二个字节代表随后的字节数,每个字节都包含单个像素的颜色索引(成颜色表)。[...]在绝对模式下,每个运行必须在单词边界上对齐。
大概,这意味着必须以奇数长度运行的长度必须为零(尽管未指定,但我认为在这种情况下,单词长16位)。
但是,文档中的示例包括一个符合奇数长度的运行,该长度不会在单词边界上结束:
[03 04] [05 06] [00 03 45 56 67] [02 78] [00 02 05 01] [02 78] [00 00] [09 1E] [00 01]
00 03 45 56 67
应该是00 03 45 56 67 00
?
我修改了一个8位索引的颜色位图,结果似乎表明运行的确应为零,以在16位单词边界上结束(因此00 03 45 56 67
应该是CC_3)。
详细信息:
-
在Microsoft Paint(版本1607,Windows 10包含),我在以下布置中创建了一个包含红色(R),绿色(g)和蓝色(b)像素的4x4位图:
BRBR BBBB GGBB RRRG
- 我将文件保存为256色位图(没有选择使用索引颜色或运行长度编码)。
- 我在GNU映像操纵程序(GIMP)中打开了该文件,将颜色模式更改为索引(通过Image> Mode> Mode>索引),并将其导出为" Windows BMP",检查了"运行长度编码"选项。
- 我制作了文件的副本,并在HXD(十六进制编辑器)中打开。
-
在此阶段,像素数据表示如下(请注意,根据文档,图像从左下开始,并从左到右进行进展):
03 4F // Three red pixels 01 71 // One green pixel 00 00 // EOL 00 04 71 71 E8 E8 // GGBB 00 00 // etc. 04 E8 00 00 00 04 E8 4F E8 4F 00 01 // EOF
- 在像素数据区域的开始时,我替换了
03 4F
(以编码模式指定的三个红色像素;请注意,用00 03 4F 4F 4F
将红色映射到颜色表中的索引0x4f = 79)没有零填充),更新了标题中的文件大小并保存了更改。 - 在GIMP和油漆中打开时,修改后的文件被错误地渲染:前两个行中的像素和右下的像素是黑色的,第三行中的最后两个像素为绿色而不是蓝色。<<<<<<<<<<<<<<<<<<<<<<<<<<<</li>
- 在HXD中,我将
00 03 4F 4F 4F
更改为00 03 4F 4F 4F 00
(在绝对模式下指定的三个红色像素,添加了零字节以结束在16位单词边界上的运行),更新了标题中的文件大小,并保存了该文件大小文件。 - 在GIMP中打开时,现在正确渲染了该文件。当用油漆打开时,顶行是黑色的(我怀疑我忽略了更新涂料但不使用GIMP使用的标头字段),但否则图像是正确的。
在问题和现有答案中加强索赔,我找到了一个文档(http://www.martinreddy.net/gfx/gfx/2d/bmp.txt)BMP格式规范。
有趣的是,在那里显示了相同的示例,除了添加了正确的填充字节(下面是报价):
Absolute mode is signaled by the first byte in the pair being set to zero and
the second byte to a value between 0x03 and 0xFF. The second byte represents
the number of bytes that follow, each of which contains the color index of a
single pixel. Each run must be aligned on a word boundary. Following is an
example of an 8-bit RLE bitmap (the two-digit hexadecimal values in the
second column represent a color index for a single pixel):
Compressed data Expanded data
03 04 04 04 04
05 06 06 06 06 06 06
00 03 45 56 67 00 45 56 67
02 78 78 78
00 02 05 01 Move 5 right and 1 down
02 78 78 78
00 00 End of line
09 1E 1E 1E 1E 1E 1E 1E 1E 1E 1E
00 01 End of RLE bitmap