嵌入式算法10---行程编码

1、行程编码

嵌入式设备采集的数据,变化比较平缓,长时间趋于稳定的状态,其采样结果会有大量连续且相同的数值,对应这些数据,常规的压缩算法在硬件资源有限的嵌入式设备无法运行,代码空间和RAM要求不能满足的情况下,简单有效的行程编码不失为一种最佳选择。

行程编码(Run Length Encoding,RLE), 又称游程编码,主要思路是将一个相同值的连续串用一个代表值和串长来代替。例如字符串“AAABBBBCCCCCJJJJJJ”,可以用“3A4B5C6J”来记录,原本长度18字节的字符串使用8个字节即可无损表达。

为便于直观显示,举例的编码是进行了特殊描述,“3A4B5C6J”实际应该是 3‘A’ 4‘B’ 5‘C’ 6‘J’,字符个数的数字转为字符显示,例如3变成了‘3’显示更易理解。
以下举例也是这个规则,正确方式是应该是以%X查看,如果不明白3和‘3’的区别,请先补习C基础。

2、局限性与改进型

行程编码的原理简单,但算法需结合实际,统计数据出现概率与次数,有针对性的改进编码,提高压缩比。

  1. 按前面范例规则,原始数据全部都不连续出现,如源字符串“ABCDE”编码后变成“1A1B1C1D1E”,其长度反而扩大一倍,因此对于随机出现没有连续字符的数据,基本规则不适合。
  2. 可以改进为编码时查询连续出现的才进行编码,只出现一次的直接使用原始值,不进行处理。如"111233334"编码为“31 2 43 4”,字符2和4只出现一次,编码时忽略。但缺点是解码无法分辨其中的2是数值出现次数,还是数值本身。
  3. 因此对编码与未编码的分段,使用标记区分段。例如定义编码段以E开头,则"111233334"编码为“E31 2 E43 4”,解析时只对出现E的字段才进行解析,单个字段直接原样替换。
  4. 增加段标记后,每个连续段编码后都是3个字节,如果相同字符值出现2次,如“11335577”则编码后为“E21 E23 E25 E27”,其长度超过原始长度,因此可以改为,只有连续出现的次数大于3的才进行编码。例如"112223333"编码为“11 222 E43”。
  5. 因为表示字符连续次数的数字分配了一个字节,某个字符如连续出现255次以上,则拆分为两部分。如“AAA…AAA”连续出现300次,则编码以%X显示为 45 FF 41 45 2D 41 ,其中’E’=0x45,‘A’=0x41。

45 FF 41 //行程编码 255 个’A’
45 2D 41 //行程编码 45 个’A’

  1. 前面描述编码段的头以’E’作为标记,字符连续出现次数大于3的才进行编码处理的,因此 ‘E’ 后面的数字肯定大于3。如果源数据中存在‘E’,则以 ‘E’0转义,这样才能解析分辨,是真实的’E’,还是编码标记。
    如 “EEEEE”编码后以16进制显示为 45 00 45 00 45 00 45 00 45 00 ,结果是长度增加一倍,因此定义合理的标记很关键。

选择字数据串中出现概率最小的为标记。如纯ASCII字符串(0-0x7F),选择0x80则避开该问题。

  1. 算法规则没有最好的,只有最合适的,如果认可前面的规则,可继续阅读下面的源码,包括编码和解码。

3、源码

#include "stdio.h"
#include "string.h"

//配置为数据源中出现概率最小的数
#define FLAG_ENCODE_HEAD 0x80

void log(char *head,unsigned char *data,unsigned int len)
{
   
   
    unsigned int i;

    printf("%s:",head);

    for(i=0;i<len;i++)
    {
   
   
        printf("%02X ",data[i]);
    }
    printf("\r\n");
}

//行程编码
//输入待编码的数据及长度,提供输出编码数据的缓冲区
//返回编码后的长度
int compress_encode(unsigned char *dect, unsigned char *src, unsigned int len)
{
   
   
    unsigned char last = 0, count 
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值