/* Basic RLE Compression
*
* Read the file, write compressed as frequency of each byte in sucession
* I.E
*
* 2, 4, 4, 1, 1, 1, 1, 5, 5, 5 compresses to:
* 1, 2, 2, 4, 4, 1, 3, 5 (1 two, 2 fours, 4 ones, 3 fives)
*
* Returns the saved fraction (* 100 = % compression)
*/
float compress(const char *fname, const char *cname)
{
fstream file; // original file
fstream compressed; // compressed file
char character; // read character
char next_character; // last character read
int fsize = 0; // file size
int frequency = 1; // unique byte values
int write_pos = 0;
file.open(fname, ios::in | ios::ate | ios::binary);
compressed.open(cname, ios::out | ios::trunc | ios::binary);
fsize = file.tellg();
for(int i = 0; i < fsize; i++)
{
file.seekg(i, ios::beg); // safety net
file.read((char*)&character, sizeof(char)); // get current character
next_character = file.peek();
if(next_character != character)
{
compressed.seekp(write_pos, ios::beg);
compressed.write((char*)&frequency, sizeof(char));
compressed.seekp(write_pos + 1, ios::beg);
compressed.write((char*)&character, sizeof(char));
write_pos += 2;
frequency = 0;
}
frequency++;
}
file.close();
compressed.close();
return (write_pos / float(fsize));
}
void decompress(const char *fname, const char *uname)
{
fstream file;
fstream ufile;
char character;
int frequency = 0;
int fsize = 0;
int write_pos = 0;
file.open(fname, ios::ate | ios::in | ios::binary);
ufile.open(uname, ios::trunc | ios::out | ios::binary);
fsize = file.tellg();
for(int i = 0; i < fsize; i += 2)
{
file.seekg(i, ios::beg);
file.read((char*)&frequency, sizeof(char));
file.seekg(i + 1, ios::beg);
file.read((char*)&character, sizeof(char));
for(int j = 0; j < frequency; j++)
{
ufile.seekp(write_pos, ios::beg);
ufile.write((char*)&character, sizeof(char));
write_pos++;
}
}
file.close();
ufile.close();
}
/* any credit to myself if you find this useful would be extremely welcolme
* as I do spend a LOT of time ensuring that code works and is useful ect...
* before I consider posting/releasing it! :) Hope you find this useful
* took a bit of time to figure out. Any comments / suggestions feel
* free to add in below! 1o0oBhP
*/
// ps this method works well on low detail bitmaps and repeated chars!