Some algorithms for compressing images

closed account (1vRMoG1T)
RLE(Run Length Encoding)

using namespace std;

class Bitwriter{
private:
unsigned char _buff;
vector<unsigned char>& _out;
unsigned _length;

public:
Bitwriter(vector<unsigned char>& values):_buff(0),_length(0),_out(values){}
~Bitwriter(){ clear_all();}


void write_bit(unsigned bit){
_buff=_buff<<1;
_buff=_buff + (bit&1);
++_length;
if(_length==8){
_out.push_back(_buff);
_length=0;
}
}

void write(unsigned val, int l){
while (l>0){
--l;
write_bit(val>>l);
}

}
void clear_all(unsigned val=0){
while(_length>0)
write_bit(val);
}


};

class Bitreader{
private:
unsigned char _buff;
unsigned _l;
istream& _fin;
vector<unsigned> _values;
public:
Bitreader(istream& f):_fin(f),_l(0),_buff(0){}

//read big endian
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_rle(){
unsigned bit=0;
unsigned cont=1;
_values.clear();
while(cont==1){
bit=(bit<<1)|read_bit();
cont=bit;
bit=0;
read_seven_bits();
}
int val=0;
for(size_t i=0; i<_values.size();++i){
if(_values[i]!=0)
val+=1<<i;
}
return val;
}
void read_seven_bits(){
unsigned n=7;
vector<unsigned> temp;
while(n>0){
n--;
unsigned val=read_bit();
temp.push_back(val);
}
reverse(temp.begin(),temp.end());
copy(temp.begin(),temp.end(),back_inserter(_values));
}

//read little endian
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;
vector<int>::reverse_iterator it;
copy(v.begin()+24,v.end(),back_inserter(temp));
copy(v.begin()+16,v.begin()+24,back_inserter(temp));
copy(v.begin()+8,v.begin()+16,back_inserter(temp));
copy(v.begin(),v.begin()+8,back_inserter(temp));
reverse(temp.begin(),temp.end());
for(size_t i=0; i<temp.size();++i){
if(temp[i]!=0)
val+=1<<i;
}
return val;
}
};


class RLE{
private:
string magic;
unsigned h;
unsigned w;
unsigned first_bit;
public:
RLE(){}

void load_RLE(string& in){
ifstream infile(in,ifstream::binary);
string magic="RLE";
infile.read(reinterpret_cast<char*>(&magic[0]),3);
if(magic!="RLE")
cout<<"Errore nome file"<<endl;
Bitreader br(infile);
w=br.read_le(32);
h=br.read_le(32);
first_bit=br.read(8);
unsigned cont=0;
vector<unsigned char> pixels;
unsigned c;

while(cont<(w*h)){
if(infile.eof()) break;
c=br.read_rle();
for(size_t i=0; i<c+1; ++i)
pixels.push_back(first_bit);
cont+=c+1;
if(first_bit==0) first_bit=255;
else first_bit=0;
}
ofstream outfile("output.pgm",ofstream::binary);
outfile<<"P5"<<endl;
outfile<<w<<" "<<h<<endl;
int max=255;
outfile<<max<<endl;
for(size_t i=0; i<pixels.size();++i)
outfile<<pixels[i];
outfile.close();
}


};

int main(int argc, char* argv[]){
string in=argv[1];
RLE rl;
rl.load_RLE(in);
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
LZW

using namespace std;

class Bitwriter{
private:
private:
unsigned char _buff;
vector<unsigned char>& _out;
unsigned _length;

public:
Bitwriter(vector<unsigned char>& values):_buff(0),_length(0),_out(values){}
~Bitwriter(){ clear_all();}


void write_bit(unsigned bit){
_buff=_buff<<1;
_buff=_buff + (bit&1);
++_length;
if(_length==8){
_out.push_back(_buff);
_length=0;
}
}


void write(unsigned val, int l){
while (l>0){
--l;
write_bit(val>>l);
}

}
void clear_all(unsigned val=0){
while(_length>0)
write_bit(val);
}


};

class Bitreader{
private:
unsigned char _buff;
unsigned _l;
istream& _fin;
public:
Bitreader(istream& f):_fin(f),_l(0),_buff(0){}

unsigned read(unsigned char 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--;
return (_buff>>_l)&1;
}
};

class LZW{

public:
LZW(){}
void codification(const string& in, const string& out){
cout<<"start"<<endl;
ifstream infile(in, ifstream::binary);
ofstream outfile(out,ofstream::binary);
typedef vector<unsigned char> myvec;
typedef myvec::iterator it;
myvec values;
unsigned char c;
while(infile>>noskipws>>c)
values.push_back(c);
vector<string> dic;
create_dic(dic);
it it_v=values.begin();
string s="";
vector<unsigned> output;
unsigned pos;
vector<unsigned> lunghezze;
while(it_v!=values.end()){
s.insert(s.end(),1,*it_v);
vector<string>::iterator trovato=find(dic.begin(),dic.end(),s);
if(trovato!=dic.end()){
++it_v;
pos=distance(dic.begin(),trovato);
}
else{
output.push_back(pos);
int l=ret_l(dic.size());
lunghezze.push_back(l);
dic.push_back(s);
if(dic.size()==500){
dic.clear();
create_dic(dic);
}

s.clear();
}
}
if(s.size()!=0){
output.push_back(pos);
int l=ret_l(dic.size());
lunghezze.push_back(l);
}


myvec scrivi;
string magic="LZW";
copy(magic.begin(),magic.end(),back_inserter(scrivi));
unsigned n=values.size();
vector<unsigned char> v;

copy((unsigned char*)&n,(unsigned char*)&n+4,back_inserter(v));

swap(v[0],v[3]);
swap(v[1],v[2]);
copy(v.begin(),v.end(),back_inserter(scrivi));
Bitwriter bw(scrivi);
for(size_t i=0; i<output.size();++i)
bw.write(output[i],lunghezze[i]);
bw.clear_all();
copy(scrivi.begin(),scrivi.end(),ostream_iterator<unsigned char>(outfile));

}

void decodification(const string& in, const string& out){
cout<<"start"<<endl;
ifstream infile(in, ifstream::binary);
ofstream outfile(out,ofstream::binary);
string magic="LZW";
infile.read(reinterpret_cast<char*>(&magic[0]),3);
if(magic!="LZW")
cout<<"Error!"<<endl;
Bitreader br(infile);
unsigned size=br.read(32);
string s_prev="";
string s_cur="";
vector<string> dic;
create_dic(dic);
int l=ret_l(dic.size());
unsigned i_prev=br.read(l);
s_prev=dic[i_prev];
dic.push_back(s_prev);
outfile.write(reinterpret_cast<const char*>(&s_prev[0]),s_prev.size());
unsigned nchar=1;
while (nchar<size){
l=ret_l(dic.size());
unsigned i_cur=br.read(l);
if(i_cur==(dic.size()-1)) {
dic[dic.size()-1].insert(dic[dic.size()-1].end(),1,dic[dic.size()-1][0]);
}
s_cur=dic[i_cur];
dic[dic.size()-1].insert(dic[dic.size()-1].end(),1,s_cur[0]);
if(dic.size()==500){
dic.clear();
create_dic(dic);
}
dic.push_back(s_cur);
nchar=nchar + s_cur.size();
outfile.write(reinterpret_cast<const char*>(&s_cur[0]),s_cur.size());
s_cur.clear();
}
}

unsigned ret_l(unsigned dim){
unsigned l=0;
while(dim!=0){
dim=dim/2;
++l;
}
return l;
}

void create_dic(vector<string>& v){
vector<string> v1(256,"");
v=v1;
for(size_t i=0; i<256;++i)
v[i].insert(v[i].end(),1,i);
}
};




int main(int argc, char* argv[]){
string in=argv[1];
string out=argv[2];
LZW lzw;
lzw.codification(in,out);
lzw.decodification(out,"decompression.txt");
}

Last edited on
1. You haven't asked a question
2. You duplicate posted: http://www.cplusplus.com/forum/beginner/123822/
3. You didn't format any code.

What are you looking for?
Topic archived. No new replies allowed.