Run Length Encoding (Integers)
<p>In class we were talking about RLE and our Professor showed us the following code. I tried to understand it, but I don't quite get it. So I'd be very thankful if someone could explain to me how RLE on this example works.
I do understand how to achieve the data compression but I do not understand the implemantation of the program. In the comments you will find my questions.</p>

<pre><code>// Example implementation of a simple variant of // run-length encoding and  decoding of a byte sequence

#include &lt;iostream&gt; 
#include &lt;cassert&gt;

// PRE: 0 &lt;= value &lt;= 255 
// POST: returns true if value is first byte of a tuple, otherwise false 

bool is_tuple_start(const unsigned int value) 
{ 
    assert(0 &lt;= value &amp;&amp; value &lt;= 255);
    return value &gt;= 128; //Why is it: value&gt;=128 for first Byte of tuple?
}

// PRE: 1 &lt;= runlength &lt;= 127 //Why must runlength be in this range?
// POST: returns encoded runlength byte 

unsigned int make_tuple_start(const unsigned int run_length) 
{ 
    assert(1 &lt;= run_length &amp;&amp; run_length &lt;= 127);
    return run_length + 128; //Why do I add 128?
}

// PRE: n/a 
// POST: returns true if value equals the maximal run-length 

bool is_max_runlength(const unsigned int value)  
{
    return value == 127; //same question: why is max. range 127?
}

// PRE: 128 &lt;= value &lt;= 255 //Why this range for value?
// POST: returns runlength of tuple 

unsigned int get_runlength(const unsigned int value) 
{ 
    assert(128 &lt;= value &amp;&amp; value &lt;= 255);
    return value - 128; //Why -128?
}

// PRE: n/a 
// POST: outputs value and adds a newline 

void out_byte(const unsigned int value) 
{ 
    std::cout &lt;&lt; value &lt;&lt; "\n"; 
}

// PRE: 1 &lt;= runlength &lt;= 127 and 0 &lt;= value &lt;= 255 
// POST: outputs run length encoded bytes of tuple 

void output(const unsigned int run_length, const unsigned int value) 
{ 
    assert(1 &lt;= run_length &amp;&amp; run_length &lt;= 127); 
    assert(0 &lt;= value &amp;&amp; value &lt;= 255); //Why is value now between 0 and 255?

    if (run_length == 1 &amp;&amp; !is_tuple_start(value)) 
        { 
            out_byte(value); 
        } 
    else 
        { 
            out_byte(make_tuple_start(run_length)); 
            out_byte(value); 
        }
}

// PRE: n/a 
// POST: returns true if 0 &lt;= value &lt;= 255, otherwise false 

bool is_byte(const int value) 
{ 
    return 0 &lt;= value &amp;&amp; value &lt;= 255; 
}

// PRE: n/a 
// POST: outputs error if value does not indicate end of sequence 

void check_end_of_sequence(const int value) 
{ 
    if (value != -1) 
        { 
            std::cout &lt;&lt; "error\n"; 
        } 
}

// PRE: n/a 
// POST: reads byte sequence and outputs encoded bytes 

void encode() 
{ 
    std::cout &lt;&lt; "--- encoding: enter byte sequence, terminate with -1\n";
    int value;

    std::cin &gt;&gt; value;

    if (is_byte(value)) 
        { 
            int prev_value = value; //When/Where does value Change?
            unsigned int run_length = 1;

            while(true) 
                {
                    // read next byte, stop if invalid or end of sequence 

                    std::cin &gt;&gt; value; 
                    if (!is_byte(value)) 
                        { break; }

                    // output if value has changed or maximal runlength is reached 
                    // otherwise increase length of current run 

                    if (value != prev_value || is_max_runlength(run_length)) 
                        { 
                            output(run_length, prev_value); 
                            run_length = 1; 
                            prev_value = value; 
                        } 
                    else { ++run_length; }
                }
            output(run_length, prev_value);
        }

    // output "error" if sequence terminated incorrectly 

    check_end_of_sequence(value);
}

// PRE: n/a 
// POST: reads byte sequence and outputs decoded bytes 

void decode() 
{ 
    std::cout &lt;&lt; "--- decoding: enter byte sequence, terminate with -1\n";
    int value; 

    while(true) {

        // read next byte, stop if invalid or end of sequence 

        std::cin &gt;&gt; value; //is value only a Byte? Or the whole sequence?

        if (!is_byte(value)) 
            { break; }

        // if this is a tuple output read next byte, otherwise output directly 

        if (is_tuple_start(value)) 
            {
                unsigned int run_length = get_runlength(value);

                // next must be a valid byte, otherwise this is an error 
                std::cin &gt;&gt; value; 

                if (!is_byte(value)) 
                    { 
                        value = 0; 
                        // trigger error in case value = -1 
                        break; 
                    }

                // output uncompressed tuple 

                for(int i = 0; i &lt; run_length; ++i) 
                    { 
                        out_byte(value); 
                    }
            } 

        else { out_byte(value); }
    }

    // output "error" if sequence terminated incorrectly 

    check_end_of_sequence(value);
}


int main(const int argc, const char* argv[]) 
{ 
    std::cout &lt;&lt; "--- select mode: 0 = encode / 1 = decode\n"; 

    unsigned int mode; 
    std::cin &gt;&gt; mode;

    if (mode == 0) 
        { 
            encode(); 
        } 
    else if (mode == 1) 
        { 
            decode();
        } 
    else 
        { 
            std::cout &lt;&lt; "--- unknown mode, must be 0 (encode) or 1 (decode)\n"; 
        }
}
</code></pre>

<p>I hope to get answers to my questions and that the code is readable, which was basically copy+paste from my lecture notes.</p>