RLE:Run Length Encoding(行程长度压缩算法)
Run Length Encoding(RLE)行程长度的原理是将字符串的连续重复字符用一个计数值和字符代替。
比如,数据项为
AA AA BB C0 C0 C0 C0 FF FF FF FF FF FF (13字节)
可以视为 2*AA + BB + 4*C0 + 6*FF
压缩为 02 AA 01 BB 04 C0 06 FF (8个字节)
#include <stdio.h>
#include <stdlib.h>
int RLE_enc(const char * file1, const char * file2);
int RLE_dec(const char * file1, const char * file2);
int main()
{
RLE_enc("E:\\C++programming\\file1.txt", "E:\\C++programming\\file2.txt");
RLE_dec("E:\\C++programming\\file2.txt", "E:\\C++programming\\file3.txt");
return 0;
}
int RLE_enc(const char * file1,const char * file2)
{
FILE * fp1 = fopen(file1, "rb");
if (NULL == fp1)
return -1;
计算文件大小,最大2^31-1/
fseek(fp1, 0, SEEK_END);
int n = ftell(fp1);
if ((n == -1)||(n == 0) )
return -1;
fseek(fp1, 0, SEEK_SET);
char * text = (char *)malloc(n);
if (text == NULL)
return -1;
fread(text, 1, n, fp1);
fclose(fp1);
unsigned char num = 1; //字符的个数,一个字节
int ch = text[0]; //字符
int nch = 1; //字符的种数
char * enctext= (char *)malloc(2*n);
if (enctext == NULL)
return -1;
enctext[0] = 1;
enctext[1] = ch;
for (int i = 1;i < n;i++)
{
if (ch == text[i])
num++;
else
{
enctext[2*nch-2] = num;
enctext[2*nch-1] = ch;
num = 1;
ch = text[i];
nch++;
}
}
enctext[2 * nch - 2] = num; //最后一个字符个数
enctext[2 * nch - 1] = ch; //最后一个字符
free(text);
FILE * fp2 = fopen(file2,"wb");
if (NULL == fp2)
return -1;
fwrite(enctext,1,2*nch,fp2);
fclose(fp2);
free(enctext);
return 0;
}
int RLE_dec(const char * file1, const char * file2)
{
FILE * fp1 = fopen(file1,"rb");
if (fp1 == NULL)
return -1;
FILE * fp2 = fopen(file2, "wb");
if (fp2 == NULL)
return -1;
char buf[2];
unsigned char num;
char ch;
while (!feof(fp1))
{
if(fread(buf,1,2,fp1)!=2) //读取两个字节:字符个数+字符
break;
num = buf[0];
ch = buf[1];
char * chbuf = (char *)malloc(num);
for (int i = 0;i < num;i++)
chbuf[i] = ch;
fwrite(chbuf,1,num,fp2);
free(chbuf);
}
fclose(fp1);
fclose(fp2);
return 0;
}