在C中寻找没有STM32动态分配的数据压缩实现

Looking for a data compression implementation in C without dynamic allocation for STM32

我正在寻找可以在 STM32L4 上 运行 的无损数据压缩算法实现。数据是 ECG 曲线(所以基本上是一组 16 位数值,彼此相对接近)。

我发现了不同的实现方式,例如 miniz,但它们都使用动态内存分配(我想避免这种情况),而且非常复杂且耗费资源。

我读过 this post 但没有真正的答案。我想避免修改现有实现以摆脱动态分配,因为此功能(数据压缩)不是我的主要优先事项。

我不需要最先进的算法,而是一种简单的、资源有限的算法,即使压缩比不是最好的,也可以在无线发送数据时节省一些带宽。

您是否知道适合的算法?

我正在使用 https://github.com/pfalcon/uzlib

它使用 malloc 但很容易修改和使用固定大小的缓冲区。

看看试试

根据您的数据示例,您可以自己进行非常简单的压缩,无需外部库,速度更快,压缩率可能更高。

如果您查看数据,数字之间的差异通常小于 8 位整数的大小 (int8_t),它可以处理 -128 .. + 127 之间的数字。

这意味着如果范围在 -127 .. + 127 之间,您可以始终存储这些数字之间的差异。

Number -128 (0xff) 可能很神奇,这意味着这个数字后面将跟一个 16 位数字。这个幻数也将用作同步数,也将在开始时使用。

或者使用 4 位数字而不是 8 位数字(但这会更复杂一些)(幻数将为 -8 并且它存储范围为 -7 .. +7。你在一个字节中存储两个数字.

因此,以您的示例为例:

input    |  output 8bit  |  output 4bit
int16    |  int8  int16  |  int4  int16
---------+---------------+---------------
  -12    |  -128    -12  |    -8    -12
  -12    |     0         |     0
  -12    |     0         |     0
  -11    |     1         |     1
  -15    |    -4         |    -4
   -8    |     7         |     7
  -16    |    -8         |    -8    -16
  -29    |   -13         |    -8    -29
   28    |    57         |    -8     28
  169    |  -128    169  |    -8    141
  327    |  -128    327  |    -8    158
  217    |  -110         |    -8    217
  -79    |  -128    -79  |    -8    -79
  -91    |   -12         |    -8
  -59    |    32         |    -8    -59
  -41    |    18         |    -8    -41
  -36    |     5         |     5
  -29    |     7         |     7
  -26    |     3         |     3
  -24    |     2         |     2
  -22    |     2         |     2
  -19    |     3         |     3
  -14    |     5         |     5
  -14    |     0         |     0
  -12    |     2         |     2
  -10    |     2         |     2
  -10    |     0         |     0
   -5    |     5         |     5
   -2    |     3         |     3
    1    |     3         |     3
    5    |     4         |     4
   10    |     5         |     5
   15    |     5         |     5
   17    |     2         |     2
   21    |     4         |     4
   22    |     1         |     1
   20    |    -2         |    -2
   20    |     0         |     0
   15    |    -5         |    -5
    9    |    -6         |    -6
    2    |    -7         |    -7
   -6    |    -8         |    -8    -6
---------+---------------+---------------------
   42    |    42      4  |    42    11     count
   84    |    42      8  |    21    22     bytes
   84    |        50     |       43        bytes total
  100%   |        60%    |       51%       compression ratio

因此,如您所见,使用非常简单的算法可以获得非常好的结果。

还可以找到该算法的其他改进,例如对相同数据进行分组,或者也可以在幻数之后压缩 16 位数据数据。例如,在幻数之后,您可以指定后面的 16 位数字(未压缩数字)

但一切都取决于你的数据。