Basic RLE File compression routine

1o0oBhP 1 Tallied Votes 2K Views Share

The RLE (Run length encoding) compression method compresses a file by writing repeated data as a byte containing the length, then a byte of the data itself. The 'real' RLE method involves writing control bytes. The first bit says whether the following data is compressed or uncompressed. The remaining bits control the length. For example

1, 1, 2, 3, 3, 4, 1, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6

compresses like this:

8 (8 + 0 for uncompressed bit), 1, 1, 2, 3, 3, 4, 1, 5, 13 (12 + 1 for compressed bit), 6 -> which is a control byte suggesting an uncompressed run of 8 numbers then a control byte suggesting a compressed run of 12 6's

This snippet is a simplified version which just reads bytes 'on the fly' and writes a byte pair - frequency first then the character. It has more wastage as it will try to compress everything (so 1, 2, 3 becomes 1, 1, 1 ,2, 1, 3) but is useful for long repeated sections (6,6, 6, 6 becomes 4, 6)

/* 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!
tlox 0 Newbie Poster

to me this was useful.thank you.

t10000 0 Newbie Poster

Thanks,

Thokozani 0 Newbie Poster

using c++ programing How do I program something like (yes,no yes no,no yes no) to something like 3yes,4no

Thokozani 0 Newbie Poster

for Data compression using c++ programing How do I program something like (yes,no yes no,no yes no) to something like 3yes,4no

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.