Huffman 1
#include<iostream>
#include<fstream>
#include<string>
#include<vector>
#include<map>
#include<iterator>
#include<algorithm>
using namespace std;
struct tupla{
unsigned _l;
unsigned char _c;
tupla():_l(0),_c(0){}
tupla(unsigned l,unsigned char c):_l(l),_c(c){}
};
class Bitreader{
private:
unsigned _l;
unsigned char _buff;
istream& _f;
public:
Bitreader(istream& f):_l(0),_buff(0),_f(f){}
unsigned read(unsigned nbit){
unsigned val=0;
while(nbit>0){
nbit--;
val=(val<<1)|read_bit();
}
return val;
}
unsigned read_bit(){
if(_l==0){
_l=8;
_f.read(reinterpret_cast<char*>(&_buff),1);
}
_l--;
return (_buff>>_l)&1;
}
unsigned read_le(unsigned n){
unsigned int val=0;
unsigned cont=0;
vector<int> v;
while (n>0){
n--;
unsigned bit=read_bit();
v.push_back(bit);
}
vector<int> temp;
copy(v.begin()+8,v.end(),back_inserter(temp));
copy(v.begin(),v.begin()+8,back_inserter(temp));
for(size_t i=0; i<temp.size();++i){
val=val<<1;
val+=temp[i]&1;
}
return val;
}
void find_codes(vector<unsigned char>&v,map<string,unsigned char>& m,unsigned size){
unsigned bit=0;
unsigned cont=0;
string code="";
map<string,unsigned char>::const_iterator it;
while (cont<size){
bit=read_bit();
if(bit==1)
code.append("1");
else code.append("0");
it=m.find(code);
if(it!=m.end()){
v.push_back((*it).second);
cont++;
code.clear();
}
}
}
};
string canonical_bin(unsigned c, unsigned l){
unsigned q=c;
unsigned r=0;
vector<unsigned> vec;
unsigned cont=0;
string code;
while(q!=0){
r=q%2;
q=q/2;
vec.push_back(r);
}
cont=vec.size();
for(size_t i=0; i<l-cont; ++i)
vec.push_back(0); //inserisco gli zeri davanti se necessario per completare la lunghezza
for(size_t i=vec.size(); i>0; --i)
if(vec[i-1]==0)
code.append("0");
else code.append("1");
return code;
}
void generate_canonical_code(vector<tupla>& vt,map<string,unsigned char>& m){
unsigned can_code=0;
vector<tupla>::iterator it_last=vt.begin();
vector<tupla>::iterator it_prev=vt.begin();
string str_code=canonical_bin(can_code,(*it_last)._l);
m[str_code]=(*it_last)._c;
it_last++;
while (it_last!=vt.end()){
can_code=(can_code+1)<<((*it_last)._l-(*it_prev)._l);
str_code=canonical_bin(can_code,(*it_last)._l);
m[str_code]=(*it_last)._c;
it_last++;
it_prev++;
}
}
void loadFile(string& in){
ifstream infile(in,ifstream::binary);
Bitreader br(infile);
unsigned w=br.read_le(16);
unsigned h=br.read_le(16);
vector<tupla> table;
unsigned val;
val=br.read(8);
unsigned cont=1;
unsigned char c;
for(size_t i=0;i<val;++i){
c=br.read(8);
tupla t(cont,c);
table.push_back(t);
}
val=br.read(8);
while(val!=255){
cont++;
for(size_t i=0;i<val;++i){
c=br.read(8);
tupla t(cont,c);
table.push_back(t);
}
val=br.read(8);
}
map<string, unsigned char> can_table;
generate_canonical_code(table,can_table);
vector<unsigned char> pixels;
br.find_codes(pixels,can_table,w*h);
ofstream out("output.pgm",ofstream::binary);
out<<"P5"<<endl;
out<<w<<"\t"<<h<<endl;
out<<255<<endl;
for(size_t i=0; i<pixels.size();++i)
out<<pixels[i];
}
int main(int argc, char* argv[]){
string in=argv[1];
loadFile(in);
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Huffman 2
#include <iostream>
#include <fstream>
#include <algorithm>
#include <map>
#include <iterator>
#include <string>
#include <vector>
using namespace std;
class BitWriter{
private:
ostream& _fout;
unsigned char _l;
unsigned char _buff;
public:
BitWriter(ostream& f):_fout(f),_buff(0),_l(0){}
void write(unsigned int val, unsigned char l){
while (l>0){
l--;
write_bit(val>>l);
}
}
void write_bit(unsigned int val){
_buff=_buff<<1;
_buff=_buff+(val&1);
_l++;
if (_l==8)
{
_fout.write(reinterpret_cast<const char*>&_buff, 1);
_buff=0;
_l=0;
}
}
void clear_all(){
while(_l>0){
write_bit(0);
}
}
};
class BitReader{
private:
unsigned char _buff;
unsigned _l;
istream& _fin;
vector<unsigned> _values;
public:
BitReader(istream& f): _fin(f),_buff(0),_l(0){}
//legge in bigEndian
unsigned read(unsigned n){
unsigned int val=0;
while (n>0){
n--;
val=(val<<1)|read_bit();
}
return val;
}
unsigned read_bit(){
if(_l==0)
{
_l=8;
_fin.read(reinterpret_cast<char*>(&_buff), 1);
}
_l--;
unsigned bit=(_buff>>_l)&1;
return bit;
}
unsigned read_he(const map<string, unsigned char> & m){
map<string, unsigned char>::const iterator it;
bool exit=false;
unsigned char val=0;
string code="";
unsigned last_char;
while (exit==false){
val=read_bit();
if (val==0)
code.append("0");
else
code.append("1");
it=m.find(code);
if (it!=m.end()){
exit=true;
last_char=(*it).second;
}
}
return last_char;
}
};
struct tupla{
unsigned _l;
unsigned char _c;
tupla (unsigned l, unsigned c):_l(l),_c(c){}
};
class HuffmanDec{
private:
unsigned tabel_lem;
unsigned ndati;
vector<tupla> table;
map<string,unsigned char> canonical_table;
public:
HuffmanDec(){
void loadHD (string& in){
ifstream infile(in,ifstream::binary);
BitReader br(infile);
tabel_lem=br.read(8)+1;
for (size_t i=0; i<tabel_lem; ++i){
unsigned l=br.read(8);
unsigned char c=br.read(8);
tupla t(l,c);
table.push_back(t);
}
ndati=br.read(32);
generate_canonical_code();
unsigned cont=0;
ofstream outfile="output.txt";
BitWriter bw(outfile);
while (cont<ndati){
cont++;
unsigned c=br.read_he(canonical_table);
bw.write(c,8);
}
bw.clear_all();
}
void generate_canonical_code(){
unsigned can_code=0;
vector<tupla>::iterator it_last=table.begin();
vector<tupla>::iterator it_prev=table.begin();
string str_code=canonical_bin(can_code,(*it_last)._l);
canonical_table[str_code]=(*it_last).c;
it_last++;
while (it_last!=table.end()){
can_code=(can_code+1)<<((*it_last)._l-(*it_prev)._l);
str_code=canonical_bin(canonical_code,(*it_last)._l);
canonical_table[str_code]=(*it_last).c;
it_last++;
it_prev++;
}
}
string canonical_bin(unsigned c, unsigned l){
unsigned r=0;
unsigned q=c;
vector<unsigned> vec;
vector<unsigned> temp;
string code;
while (q!=0){
r=q%2;
q=q/2;
vec.push_back(r)
}
temp=vec;
for (size_t i=0; i<l-temp.size(); ++i){
//inserisco degli zeri per completare la sequenza
vec.push_back(0);
}
for (size_t i=vec.size; i>0; --i)
if(vec[i-1]==0)
code.append("0");
else
code.append("1");
return code;
}
}
};
int main(int argc, char* argv[]){
string in=argv[1];
HuffmanDec hd;
hd.loadHD(in);
}