RLE压缩算法

RLE压缩算法(下简称RLE算法)的基本思路是把数据按照线性序列分成两种情况:一种是连续的重复数据块,另一种是连续的不重复数据块。

RLE算法的原理就是用一个表示块数的属性加上一个数据块代表原来连续的若干块数据,从而达到节省存储空间的目的。一般RLE算法都选择数据块的长度为 1 字节,表示块数的长度也用1字节表示,对于颜色数小于 256 色的图像文件或文本文件,块长度选择 1 字节是比较合适的。可以参照这里

RLE全称(run-length encoding),翻译为游程编码,又译行程长度编码,又称变动长度编码法(run coding),在控制论中对于二值图像而言是一种编码方法,对连续的黑、白像素数(游程)以不同的码字进行编码。游程编码是一种简单的非破坏性资料压缩法,其好处是加压缩和解压缩都非常快。其方法是计算连续出现的资料长度压缩。

如图为RLE算法描述

RLE在用于二进制多重复的情况下比较好, 特点是可以做到无损压缩, 但是用于字符多且重复性差的情况下可能做到事倍功半, 比如 ABCDEFG经压缩后将成为1A1B1C1D1E1F1G, 字符串整整扩大了一倍.

为了模拟出有重复性的数据, 我以如下方式进行数据生成:

#include<bits/stdc++.h>
using namespace std;

int main(){
	freopen("file.txt","w",stdout);	//输出重定向,输出到文件
	srand(time(0));	//以当前时间作为种子
	char x;
	for(int i = 0; i <= 10000000; ++i){
		x = 'a' + rand()%26;
		cout<<x<<x<<x<<x;
	}
	return 0;
}

RLE算法代码:

编写一个程序,可以在命令行输入参数,完成指定文件的压缩解压,命令行参数如下

rle file1 –c(-d) file2

第一个参数为可执行程序名称,第二个参数为原始文件名,第三个参数为压缩或解压缩选项,第四个参数为新文件名

#include<bits/stdc++.h>
using namespace std;

void zip(char* filename,char *outfile){
	FILE *in, *out;
	int filelen;
	char cur, tmp;	
	if(!(in = fopen(filename,"rb")))
		cout<<"文件打开失败"<<endl;
	else
	{
		out = fopen(outfile,"wb");
		cur = fgetc(in);
		tmp = cur;
		filelen = 1;
		while(!feof(in)){
			cur = fgetc(in);
			if(cur == tmp){
				filelen++;
			}
			else{
				fputc(filelen+'0',out);
				fputc(tmp,out);
				tmp = cur;
				filelen = 1;
			}
		}
	}
	fclose(in);
	fclose(out);
}	

void unzip(char *filename,char *outfile){
	FILE *in, *out;
	int filelen;
	char cur;	//光标
	if(!(in = fopen(filename,"rb")))
		cout<<"文件打开失败"<<endl;
	else
	{
		out = fopen(outfile,"wb");
		while(!feof(in)){
			filelen = fgetc(in)-'0';
			if(feof(in))break;	//feof的问题,折腾了好一会,不好表述,总之在feof应当在每一次读操作之后判断是否到文件末, 不然会造成多读一次的错误
			cur = fgetc(in);
			while(filelen--)
				fputc(cur,out);
		}
	}
	fclose(in);
	fclose(out);
}	


int main(int argc,char *argv[]){
	if(!strcmp(argv[2], "-d")){
		unzip(argv[1], argv[3]);
		cout<<"decompress finished"<<endl;
	}

	else if(!strcmp(argv[2],"-c")){
		zip(argv[1], argv[3]);
		cout<<"compress finished"<<endl;
	}
	else
		cout<<"输入参数有误,请重新检查,-c : compress; -d : decompress"<<endl; 
	return 0;
}

其中应用到了两个之前没用过的函数fgetc和fputc, 这里简单记录一下:

  1. fgetc是一种计算机C语言中的函数。意为从文件指针stream指向的文件中读取一个字符,读取一个字节后,光标位置后移一个字节。函数格式:int fgetc(FILE *stream)
  2. fputc函数功能: 将字符ch写到文件指针fp所指向的文件的当前写指针的位置。函数格式:int fputc (int c, FILE *fp)

结果:

 源文件----35MB

 压缩后文件----15MB

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值