我的主要项目之一是微控制器的显示库。作为其中的一部分,我有一组字体(位图)和图标(alpha 通道)。
由于微控制器中的资源(闪存和 RAM)有限,我正在寻找更好的方法来存储这些字体和图标的数据。
我倾向于对数据使用分离平面排列(如使用的 Amiga 上的 ILBM) - 也就是说,不是将每个像素的所有位存储在一起,而是将整个图像的所有第一位存储在一起,然后是第二位等。这对于处理不是二次幂的图像深度变得更有效(您是否尝试将 3 位数据打包成 8 位数据流?)。
然后我还想压缩每个位平面。RLE 似乎是最明智的。但是,由于我现在使用的是比特流,而不是整数,我想知道实现 RLE 的最佳方式是什么。
我可以坚持传统的方法来处理 8 个块中的位并查找重复的字节(2 个或更多相同,替换为 2 相同,然后计算运行中的数量),但我看不到当涉及到将包含一个位平面的按位数据时,那就太好了。(顺便说一下,ILBM 使用了多种这种逐字节的方法——将数据纯粹作为字节处理,并根据需要重复它们,并使用定义如何处理下一个字节的“标题”字节)。
另一种方法是使用交替位计数方法。即,开始假设该位为 0,并记录运行中该位的编号。然后切换到 1 并记录运行中 1 的位数。然后再次切换回0并记录位数。等等。
同样,如果您长时间运行相同的位,那就太好了,但是一旦您获得快速的位交替,您最终会占用大量空间(例如 8 位01010101
可能最终成为 8 个字节[1,1,1,1,1,1,1,1]
)。
这里任何事情的主要警告是它必须是高效的 - 在 CPU 中解压缩它,并在内存中保存任何工作缓冲区,同时它解压缩。这就是为什么我在考虑 RLE 而不是其他任何方法。
所以我想我正在寻找我错过的想法。压缩单个比特流并在以字节为中心的系统中表示压缩数据的最佳实现是什么?
一个示例字形(十进制):
00 00 02 14 03 00 00 00
00 00 09 13 10 00 00 00
00 00 13 05 13 00 00 00
00 05 12 00 12 06 00 00
00 11 15 15 15 11 00 00
00 14 02 00 01 14 00 00
08 12 00 00 00 12 08 00
11 07 00 00 00 07 12 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
因此,位平面 0-3 将是
0 1 2 3
00001000 00111000 00010000 00010000
00111000 00001000 00010000 00111000
00111000 00000000 00111000 00101000
01000000 00000100 01101100 00101000
01111100 01111100 00111000 01111100
00001000 01100100 01000100 01000100
00000000 00000000 01000100 11000110
11000100 11000100 01000110 10000010
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000
但是,这种大小的字形我什至不太可能尝试压缩。它小到毫无意义。但是,它说明了位平面的分层以及位流相对于原始数据的外观。