⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rlezip.cpp

📁 自己写的RLEZIP
💻 CPP
字号:
#include <fstream>
#include <iostream>
#include <windows.h>
#include <direct.h>
#include <string>
#include <iomanip>

using namespace std;
ifstream fin;
ofstream fout;

int totalinsize = 0, outsize = 0;

void rle_rep1(unsigned char *out, unsigned int *outpos, unsigned char marker, unsigned char symbol)
{
	unsigned int idx;
	idx = *outpos;
	if(symbol == marker)
	{
		out[idx++] = marker;
		out[idx++] = 0;
	}
	else
		out[idx++] = symbol;
	*outpos = idx;
}

void rle_rep(unsigned char *out, unsigned int *outpos, unsigned char marker, unsigned char symbol, unsigned int count )
{
	unsigned int i, idx;
	idx = *outpos;
	if(count <= 3)
	{
		if(symbol == marker)
		{
			out[idx++] = marker;
			out[idx++] = count - 1;
		}
		else
			for(i = 0; i < count; ++ i)
				out[idx++] = symbol;
	}
	else
	{
		out[idx++] = marker;
		count--;
		if(count >= 128)
			out[idx++] = (count >> 8) | 0x80;
		out[idx++] = count & 0xff;
		out[idx++] = symbol;
	}
	*outpos = idx;
}

void rlezip_file(char *name)
{
	int insize, t1 = 0, t2 = 0;
	unsigned char *in, *out;
	unsigned char byte1, byte2, marker;
	unsigned int  inpos, outpos = 0, count, i, histogram[256];

   	fin.seekg (0, ios::end);
	insize = fin.tellg(); 
	fin.seekg (0, ios::beg);
	totalinsize += insize;
	outsize = insize * 257 / 256 + 60;
	in = new unsigned char[insize];
	out = new unsigned char[outsize];
	if (!in || !out)
	{
		cout <<"内存不足!" <<endl;
		return ;
	}
	fin.read((char*)in, insize);
	fout <<"[ff+" <<name <<"]";
	if (insize < 1)
	{
		fout.put(0);
		fout <<"[/ff]";
		fout.close();
		return ;
	}
    for(i = 0; i < 256; i++)
        histogram[i] = 0;
    for(i = 0; i < insize; i++)
        histogram[in[i]]++ ;
    marker = 0;
    for(i = 1; i < 256; ++ i)
        if(histogram[i] < histogram[marker])
            marker = i;
    out[0] = marker; outpos = 1; byte1 = in[0];
    inpos = 1; count = 1;
    if(insize >= 2)
    {
        byte2 = in[inpos++];
        count = 2;
        do
        {
            if(byte1 == byte2)
            {
                while((inpos < insize) && (byte1 == byte2) && (count < 32768))
                {
                    byte2 = in[inpos++];
                    count++;
                }
                if(byte1 == byte2)
                {
                    rle_rep(out, &outpos, marker, byte1, count);
                    if(inpos < insize)
                    {
                        byte1 = in[inpos++];
                        count = 1;
                    }
                    else
                        count = 0;
                }
                else
                {
                    rle_rep(out, &outpos, marker, byte1, count-1);
                    byte1 = byte2;
                    count = 1;
                }
            }
            else
            {
                rle_rep1(out, &outpos, marker, byte1);
                byte1 = byte2;
                count = 1;
            }
            if(inpos < insize)
            {
                byte2 = in[inpos++];
                count = 2;
            }
        }
        while((inpos < insize) || (count >= 2));
    }
    if(count == 1)
        rle_rep1( out, &outpos, marker, byte1 );
	fout.write((char *)out, outpos);
	fout <<"[/ff]";
	delete[] in;
	delete[] out;
}

void rlezip_dir(char *source)
{
	HANDLE  f1;
	WIN32_FIND_DATA  fData;
	char temp[50];
	fout<<"[rr+" <<source <<"]";
	strcpy(temp, "./"); strcat(temp, source);
	_chdir(temp);
	f1 = FindFirstFile(".//*", &fData);
	do
	{
		if((fData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY)
		{
			if (strcmp(fData.cFileName, ".") && strcmp(fData.cFileName, ".."))
			{
				rlezip_dir(fData.cFileName);
				_chdir("../");
			}
		}
		else 
		{
			fin.open(fData.cFileName, ios::in|ios::binary);
			rlezip_file(fData.cFileName);
			fin.close();
		} 
	}while(FindNextFile(f1,&fData));
	fout <<"[/rr]";
}

int main(int arg, char *argv[])
{
	char *destiny = argv[arg - 1], *p;
	char temp[100] = "", cur[100];
	int i, len;
	double persent;
	HANDLE  f1;
	WIN32_FIND_DATA  fData;
	fout.open(destiny, ios::out|ios::binary);
	if (!fout)
	{
		cout <<"文件错误!" <<endl;
		return 0;
	}
	if (strcmp(argv[1],"*") == 0)	//相对路径所有文件
	{
		f1 = FindFirstFile(".//*",&fData);
		do
		{
			if((fData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY)
				continue;
			fin.open(fData.cFileName, ios::in|ios::binary);
			if (!fin)
			{
				cout<<"无法读取文件!" <<endl;
				continue;
			}
			rlezip_file(fData.cFileName);
			fin.close();
		} while(FindNextFile(f1,&fData));
	}
	else if (strstr(argv[1], ":\\") != NULL)	//绝对路径压缩
	{
		len = strcspn(argv[1], "\\");
		getcwd(cur, 100);
		p = strrchr(argv[1], '\\');
		len  = strlen(argv[1]) - strlen(p) +1;
		strncpy(temp, argv[1], len);
		_chdir(temp);
		rlezip_dir(p);
		_chdir(cur);
	}
	else if (strchr(argv[1], '.') == NULL)	//相对路径文件夹压缩
	{
		rlezip_dir(argv[1]);
		_chdir("../");
	}
	else	//文件压缩
	{
		for (i = 1; i < arg -1; i++)
		{
			fin.open(argv[i], ios::in|ios::binary);
			if (!fin)
			{
				cout <<"无法读取文件!" <<endl;
				continue;
			}
			rlezip_file(argv[i]);
			fin.close();
		}
	}

	fout.close();
	fin.open(destiny, ios::in|ios::binary);
	fin.seekg (0, ios::end);
	outsize = fin.tellg(); 
	persent = (double)outsize / (double)totalinsize  * 100;
	cout <<"压缩率: "<< setiosflags(ios::fixed) <<setprecision(1) <<persent<< "%" <<endl;
	fin.close();
	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -