1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
|
using namespace std;
class 78{
public:
78(){}
void codifica(const string& in, const string& out){
map<string,unsigned> _d;
ifstream infile(in,ifstream::binary);
ofstream outfile(out,ofstream::binary);
vector<unsigned char> values;
vector<tripla> terne;
unsigned char c;
while(infile>>std::noskipws>>c){
values.push_back(c);
}
typedef vector<unsigned char>::iterator _it;
typedef map<string,unsigned>::iterator _itm;
_it it_v=values.begin();
_itm it_m;
string str="";
unsigned index=0;
unsigned cont=0;
while(it_v!=values.end()){
cont++;
str.insert(str.end(),1,*it_v);
it_m=_d.find(str);
if(it_m!=_d.end()){ //string found
it_v++;
if(cont==values.size()) break; //I need last-1 index
indice=it_m->second;
}
else{ //string not found
int l=0;
int q=_d.size();
while(q!=0){
q=q/2;
++l;
}
tripla t(indice,*it_v,l);
terne.push_back(t);
//_d.insert(_d.end(),::pair<string,unsigned>(str,last_i));
if(_d.size()==4095){
_d.clear();
}
_d[str]=_d.size()+1;
str.clear();
index=0;
it_v++;
}
}
if(str.size()!=0){ //string not empty, in the dictionary
int l=0;
int q=_d.size();
while(q!=0){
q=q/2;
++l;
}
tripla t(index,str.at(str.size()-1),l);
terne.push_back(t);
}
vector<unsigned char> output;
string magic="lz78";
copy(magic.begin(),magic.end(),back_inserter(output));
unsigned int n=values.size();
vector<unsigned char> v;
// in little endian
copy((unsigned char*)&n,(unsigned char*)&n+4,back_inserter(v));
// big endian
swap(v[0],v[3]);
swap(v[1],v[2]);
copy(v.begin(),v.end(),back_inserter(output));
Bitwriter bs(output);
for(size_t i=0; i<terne.size();++i){
bs.write(terne[i]._i,terne[i]._l);
bs.write(terne[i]._c,8);
}
bs.clear_all();
copy(output.begin(),output.end(),ostream_iterator<unsigned char>(outfile));
int i=0;
}
void decodifica(const string& in, const string& out){
ifstream infile(in, ifstream::binary);
ofstream outfile(out,ofstream::binary);
string sheader="lz78";
infile.read(reinterpret_cast<char*>(&sheader[0]),4);
if(sheader!="lz78") cout<<"Error header!"<<endl;
Bitreader br(infile);
unsigned size=br.read(32);
unsigned index=0;
unsigned char c;
string s="";
vector<string> dic;
unsigned nchar=0;
while(nchar<size){
int l=0;
int q=dic.size();
while(q!=0){
q=q/2;
++l;
}
index=br.read(l);
c=br.read(8);
if(index!=0)
s=dic[index-1];
s.insert(s.end(),1,c);
nchar+=s.size();
outfile.write(reinterpret_cast<const char*>(&s[0]),s.size());
if(dic.size()==4095){
dic.clear();
}
dic.push_back(s);
s.clear();
}
}
};
|