对于这种情况,什么是好的(de)压缩例程

时间:2009-08-28 17:51:41

标签: embedded compression run-length-encoding

我需要一个针对受限资源环境优化的FAST解压缩例程,例如具有以下特征的二进制(十六进制数据)上的嵌入式系统:

  1. 数据是面向8位(字节)的(数据总线是8位宽)。
  2. 字节值在0 - 0xFF范围内不均匀,但在每个数据集中都有泊松分布(钟形曲线)。
  3. 数据集固定为高级(烧入Flash),每组很少> 1 - 2MB
  4. 压缩可能需要花费尽可能多的时间,但是在最坏的情况下,一个字节的解压缩需要23uS,内存占用最少,因为它将在像嵌入式系统这样的受限资源环境中完成(3Mhz - 12Mhz core,2k字节RAM)。

    什么是好的减压程序?

    基本的运行长度编码似乎太浪费了 - 我可以立即看到为压缩数据添加一个标题选项以使用未使用的字节值来表示重复模式会产生惊人的性能!

    对于那些只投入了几分钟的我来说,肯定会有更好的算法来自喜欢这些东西的人吗?

    我想在PC上尝试一些“准备好”的例子,以便我可以比较基本RLE的性能。

6 个答案:

答案 0 :(得分:4)

如果您有预设的值分布,这意味着每个值的可支持性在所有数据集上都是固定的,您可以使用固定代码创建霍夫曼编码(代码树不必嵌入到数据中)。

根据数据,我会尝试使用固定代码或lz77的huffman(参见Brian的链接)。

答案 1 :(得分:4)

性能是唯一关注的两个解决方案:

  • LZO拥有GPL许可。
  • liblzf拥有BSD许可证。
  • miniLZO.tar.gz这是LZO,只是重新加入了一个更适合嵌入式开发的“缩小版”。

解压缩时两者都极快。我发现LZO在大多数情况下会创建比liblzf略小的压缩数据。你需要为速度做自己的基准测试,但我认为它们“基本上是平等的”。两者都比zlib快了几年,虽然也没有压缩(如你所料)。

LZO,特别是miniLZOliblzf都非常适合嵌入式目标。

答案 2 :(得分:2)

嗯,我想到的主要两种算法是HuffmanLZ

第一个基本上只是创建一个字典。如果你充分限制字典的大小,它应该非常快......但不要期望非常好的压缩。

后者的工作原理是添加对输出文件重复部分的反向引用。这可能只需要很少的内存来运行,除了您需要使用文件i / o来读取反向引用或将最近读取的数据块存储在RAM中。

我怀疑LZ是你最好的选择,如果重复的部分往往彼此接近。正如你所提到的,霍夫曼通过提供经常重复元素的字典来工作。

答案 3 :(得分:2)

由于这似乎是音频,我会看到差分PCM或ADPCM,或类似的东西,这会将其减少到4位/样本,而质量没有太大损失。

使用最基本的差分PCM实现,您只需在当前采样和累加器之间存储4位有符号差,并将该差值添加到累加器并移至下一个采样。如果差值在[-8,7]之外,则必须钳制该值,并且可能需要多个样本才能使累加器赶上。几乎没有内存解码非常快,只需将每个值添加到累加器并输出累加器作为下一个样本。

对基本DPCM的一个小改进,以帮助累加器在信号变大和更高音调时更快地赶上来使用查找表将4位值解码为更大的非线性范围,其中它们仍然是1除了接近零,但以更大的增量向极限方向增加。和/或您可以保留其中一个值来切换乘数。决定何时将其用于编码器。通过这些改进,您可以获得更好的质量,也可以使用每个样本3位而不是4位。

如果您的设备具有非线性μ律或A律ADC,则可以获得与8位样本的11-12位相当的质量。或者您可以在解码器中自己完成。 http://en.wikipedia.org/wiki/M-law_algorithm

可能有便宜的筹码已经为你完成所有这些,取决于你正在做什么。我没有调查过任何事情。

答案 4 :(得分:1)

您应该使用带命令行开关的压缩软件工具或可以尝试不同算法的压缩库来尝试不同的压缩算法。 使用您的应用程序的典型数据。 然后你知道哪种算法最适合你的需要。

答案 5 :(得分:1)

我在嵌入式系统中使用zlib作为启动程序,在启动时将应用程序映像解压缩到RAM。许可证非常宽松,没有GPL废话。它确实进行了一次malloc调用,但在我的情况下,我只是用一个返回指向静态块的指针和相应的free()存根替换它。我这样做是通过监视其内存分配使用情况来获得正确的大小。如果您的系统可以支持动态内存分配,那么它就会简单得多。

http://www.zlib.net/