Run_Length.h code
#ifndef Run_Length
#define Run_Length
#include <fstream>
using std::cout;
using std::endl;
using std::cerr;
using std::ios;
using std::fstream;
using std::ifstream;
using std::ofstream;
using std::string;
int Run_Length_Code(const char *input_filename, const char *output_filename )
{
fstream f_in; //設定輸入流
fstream f_out;//設定輸出流
//開檔 並設為輸入和二位元讀取
f_in.open(input_filename,ios::binary|ios::in);
if( !f_in ) //輸入檔錯誤
{
cerr << "Input file ERROR!! " << endl;
system("PAUSE");
exit(1);
}
//開檔 並設為輸出和二位元寫入
f_out.open(output_filename,ios::binary|ios::out);
if( !f_out ) //輸出檔錯誤
{
cerr << "Output file ERROR!! " << endl;
system("PAUSE");
exit(1);
}
char temp,n,num,data,next;
unsigned int Total_in=0,Total_out=0;
int cont=0;
//檔頭資訊檔
char ch[12] = {0, 255, 67, 72, 55, 95, 67, 83, 73, 69, 0, 255};
char head[12];
//檢查檔頭 是否已經壓縮過
int count = 0;
bool check = false;
for(int i = 0; i < 12; i++)
{
f_in.read(&head[i],1);
if(ch[i] == head[i]) count++;
}
if(count==12) check = true;
f_in.close(); //關檔
f_in.open(input_filename,ios::binary|ios::in);// 開檔
if (check) //有檔頭表示是壓縮過的
{ //解壓縮
cout << "The "<< input_filename <<" is a uncompressed file, compressing …";
for (int i=0;i<sizeof(ch);i++)
f_in.read(&temp,1);
while( 1 )
{
f_in.read(&n,1);
if( !f_in ) break; //如果沒有資料就跳出
Total_out+=n; //計總共傳了多少
Total_in+=n; //計總共讀了多少
f_in.read(&temp,1);
for(int i = 0; i < n; i++)
f_out.write(&temp,1);
}
}
else
{ //壓縮
bool ok=true;
cout << "The "<< input_filename <<" is a compressed file, decompressing …\n";
f_out.write(ch,sizeof(ch)); //寫入壓縮檔頭
while ( 1 )
{
if (ok) {
f_in.read(&data,1); //讀入資料
Total_in++; //讀檔計數
}
if( !f_in ) break;//若沒有資料就跳出
cont = 1; //重新開始數
while ( 1 )
{
f_in.read(&next,1);
Total_in++; //讀檔計數
if( !f_in )
{
if(cont < 256) // 如果計數沒有大於256
{
num = cont;
f_out.write(&num,1);
f_out.write(&data,1);
break;
}
else //看超過幾次256次
{
for(int i = 0; i < cont / 255; i++)
{
num = 255;
f_out.write(&num,1);
f_out.write(&data,1);
Total_out+=256;
}
//再把剩下的數字輸出
num = cont % 255;;
f_out.write(&num,1);
f_out.write(&data,1);
Total_out+=num;
break;
}//end of else
}//end of if(!f_in)
//f_in.read(&nextdata,1); //讀入下一筆資料
if ( data == next )
cont++; //當資料相同的時候 計數
if ( data != next )
{
ok=false;
if (cont < 256) // 如果計數沒有大於256
{
num = cont;
f_out.write(&num,1);//輸出次數
f_out.write(&data,1); // 輸出資料
Total_out+=2;
data = next;
break;
}
else {
//看超過幾次256次
for(int i = 0; i < cont / 255; i++)
{
num = 255;
f_out.write(&num,1);
f_out.write(&data,1);
Total_out+=256;
}
//再把剩下的數字輸出
num = cont % 255;
f_out.write(&num,1);
//f_out.write(&data,1);
data = next;
Total_out+=num;
break;
}//end of else
}//end of if !=
}//end of while
}//end of while
}//end of 壓縮
f_in.close(); //關輸入檔
f_out.close(); //關輸出檔
return (Total_in-Total_out)/Total_in*100;
}
#endif
main.cpp code
#include <iostream>
#include "Run_Length.h"
using namespace std;
int main(int argc, char *argv[])
{
char in[255],out[255]; //存檔案的名子
cout << "Please enter input filename : ";
cin >> in; //輸入檔名
cout << "Please enter output filename : ";
cin >> out;//輸出檔名
int Rate;
Rate=Run_Length_Code(in,out); //壓縮檔案or解壓縮
cout << "Finished. The compression rate : " << Rate << "%." << endl;
system("PAUSE");
return EXIT_SUCCESS;
}