C语言实现RLE(游程编码)压缩算法(粘贴就能用)
来源:互联网 发布:js监听scroll事件 编辑:程序博客网 时间:2024/05/16 06:51
RLE算法是最简单的压缩算法,作为学生党做作业不可避免的要去网上找RLE算法的代码,然而网上所有RLE压缩算法的代码都不好使,笔者在网上代码的基础上略加修改,使之粘贴即可使用。
源码来自:http://blog.csdn.net/calcular/article/details/46804919
算法思想来自:http://blog.csdn.net/orbit/article/details/7062218
感谢原作者。
原代码的问题在于,当一个字符超过127次重复之后,编码会出现错误。原作者可能并没有用足够的样本去测试,导致这个bug的出现。
废话不多说,先上代码。
bool IsRepeat3(unsigned char *in, int rest){ if (rest<2) return false; else { if (*in == *(in + 1) && *in == *(in + 2)) return true; else return false; }}int GetNoRepeat3(unsigned char *in, int rest){ if (rest <= 2) return rest + 1; else { int c = 0, restc = rest; unsigned char *g = in; while (!IsRepeat3(g, restc)) { g++; restc--; c++; if (c >= 128) return c; if (restc == 0) return c + 1; } return c; }}int Rle_Encode(unsigned char *inbuf, int insize, unsigned char *outbuf1, int outsize){ unsigned char *src = inbuf; unsigned char *outbuf = outbuf1; int rest = insize - 1; int outrest = outsize; int count = -1; int flag = 0; while (rest >= 0) { flag = 0; count = -1; if (IsRepeat3(src, rest)) { while (rest >= 0) { if (count == 127) break; if (*src == *(src + 1)) { rest--; count++; src++; } else { count++; if (count == 127) { flag = 1; } break; } } if (outrest<2) return -1; *outbuf = count | 128; outbuf++; *outbuf = *src; outbuf++; outrest -= 2; if (count != 127||flag==1) { src++; rest--; } } else { if (IsRepeat3(src, rest)) continue; int num = GetNoRepeat3(src, rest); int i; if (outrest<(num + 1)) return -1; *outbuf = num-1; outbuf++; for (i = 0; i<num; i++) { *outbuf = *(src + i); outbuf++; } src += num; rest -= num; outrest -= num + 1; } } return outsize - outrest;}int Rle_Decode(unsigned char *inbuf, int insize, unsigned char *outbuf, int outsize){ int inrest = insize; int outrest = outsize; int i; unsigned char *in = inbuf; unsigned char *out = outbuf; int ns; unsigned char tmp; while (inrest >= 0) { ns = *in+1; if (ns>129) { if ((outrest - ns + 128)<0) return -1; tmp = *(in + 1); for (i = 0; i<ns - 128; i++) { *out = tmp; out++; } in += 2; inrest -= 2; outrest -= ns - 128; } else { if ((outrest - ns)<0) return -1; in++; for (i = 0; i<ns; i++) { *out = *in; out++; in++; } inrest -= 1 + ns; outrest -= ns; } } return outsize - outrest;}
简单说下算法的原理。普通的RLE是把aabbccdd变成2a2b2c2d,这样当压缩abcd这样的数据时,不但压缩不了,还会产生冗余,所以我们需要高级点的RLE来解决这个问题。
我们知道,RLE编码是由一个个length-code字节对组成的,我们这个算法,将length字节的最高位置为标志位,如标志位为1,说明后面的一个byte连续重复X次(aaaaa这样),反之标志位为0,说明后面的X个bytes中,相邻byte互不相同(abcd这种)。标志位的后7位,表示一个X-1的整数(显然,X最大为128),当标志位为1时,X的意义和普通的RLE是一样的,当标志位为0时,X表示接下来X个bytes中相邻byte互不相同。
举例:aaaabcdefg
首先是四个连续的a,所以X=4,X-1=3,标志位为1,故length字节应为1000 0011=0x83,code字节为a,至此我们有0x83 a。
然后是6个相邻byte互不相同的字节,所以X=6,X-1=5,标志位为0,length字节为0x05,后面跟着6个bytes,bcdefg。至此,编码结束,结果为0x83 a 0x05 b c d e f g
最坏的情况,此算法会带来1/128的冗余,即使如此,比普通RLE 100%的冗余还是好上不少的。
- C语言实现RLE(游程编码)压缩算法(粘贴就能用)
- 数据压缩算法-游程编码RLE
- 游程编码与哈弗曼编码结合的压缩解压(c语言)
- RLE算法变体C语言实现
- RLE行程长度编码压缩算法
- RLE行程长度编码压缩算法
- RLE行程长度压缩算法C版本
- 压缩算法-游程算法
- 32bitTGA的rle压缩以及解压算法(二)
- 32bitTGA的rle压缩以及解压算法(一)
- 游程编码算法
- RLE 压缩算法
- RLE压缩算法
- RLE压缩算法详解
- 利用游程编码实现二值图像压缩
- GZIP压缩原理分析(13)——第五章 Deflate算法详解(五04) 预备知识(03) 游程编码
- C语言行程编码压缩算法
- RLE行程长度压缩算法C版本【转】
- C++枚举使用
- 简单的商品列表展示
- base64解码 python实现
- Python与医疗图像6
- Unable to configure Windows to Trust the Fiddler Root certificate.The LOG tab may contain more infor
- C语言实现RLE(游程编码)压缩算法(粘贴就能用)
- 生成器及注意事项
- CSS3过渡
- 程序员与公司政治
- 字符串比较大小 并且去重
- jackson json @JsonIgnore
- 【动态规划】之最长公共子序列长度(难度:1星)
- 最美英文情诗
- Nginx优化及部署LNMP