Education > Tutorials

C++ Basic RLE Compression

(1/1)

Celestialkey:

--- Code: C++ ---#include <iostream>// std::cout#include <fstream> // std::fstream#include <sstream> // std::ostringstream#include <random>/*        Run Length Encoding - RLE Example to Compression        Http://Www.CelestialCoding.com         You can go lower level then this tutorial. I will         only be looking at each byte and checking for duplicates.        You can do something similar at the macro         level (look for repeating collections of binary datasets) or even at the lowest        binary level (look for repeating binary datasets)*/ // Used to generate a ~50 meg file for compressionvoid GenerateRandomFile(){                std::fstream fout;        fout.open("myfile.txt", std::ios::out);        for (int i = 0; i < 50000000; i++){                int out = rand() % 2;                fout << char(out+65);        }        fout.close();} int main(){        GenerateRandomFile();         // Create a file handlers.        std::fstream uncompressedFile;        std::fstream compressedFile;         // Open the file to compress, check for errors        // Not we are opening in binary mode        uncompressedFile.open("myfile.txt", std::ios::ios_base::in|std::ios::ios_base::binary);        if (!uncompressedFile.is_open()){                std::cout << "Unable to open file.\n";                return -1;        }         // Store the entire file contents for later iteration        std::ostringstream fileBuff;        fileBuff << uncompressedFile.rdbuf();        std::string     sContents = fileBuff.str();         // Close the handle to the uncompressed file.        uncompressedFile.close();          // Start of the compression algorithm        // First, create a handle to a new file to write the compressed contents to        compressedFile.open("newFile.txt", std::ios::out | std::ios::binary);        if (!compressedFile.is_open()){                std::cout << "Unable to create file.\n";                return -2;        }         // Iterate through stored data and look for repititions        // Start looping through the data to get the first data to check for        unsigned                uBuffSize = sContents.size()-1;        unsigned char   ucCurrentByte;        unsigned char   ucCompareByte;        unsigned                uCurrentPosition = 0;         while (uCurrentPosition < uBuffSize){                // Select the byte to look for repeats                ucCompareByte = sContents.at(uCurrentPosition);                                // Keep track of how many times the character repeats.                // Never go above 9 repeats                unsigned                uRepeats = 0;                 // Find all repeats                while (true){                        // Increment the position by 1                        uCurrentPosition++;                         // Make sure we don't go over the buffersize                        if (uCurrentPosition > uBuffSize)                                break;                         // Grab the next byte                        ucCurrentByte = sContents.at(uCurrentPosition);                                                // Check if it repeated                        if (ucCurrentByte == ucCompareByte){                                uRepeats++;                                if (uRepeats >= 9)                                        break;                        } else {                                // If it does not, then we need to break out of this                                 // check, write what we found, then continue on to the                                 // next character                                break;                        }                }                 // Prepare the data for writting                std::ostringstream strOut;                if (uRepeats)                        // If there were more than 2 repeats write the number of instances                        // and the byte that was repeated                        if(uRepeats > 2) strOut << uRepeats << ucCompareByte;                        // Otherwise, just write out the 1-2 repeats                        else for (int a = 0; a < uRepeats; a++) strOut << ucCompareByte;                else                        // If there were no repeats, just print the character that was affected                        strOut << ucCompareByte;                 // Write the reults to file for this comparison                compressedFile << strOut.str();        }         // Close the file we were writting to.        compressedFile.close();         std::cout << "Compressed!\n";        return 0;}
Reading and decompressing the file is not show in this, but it is a simple matter of looking for identifiers (numbers 3-9 in this case) and then just repeating that data in memory to decompress the file.

Navigation

[0] Message Index

Go to full version