lesson0.cpp
//////////////////
////  Lesson 0 - Basic Arithmetic Coding
//////////////////
/*
  This lesson shows how an arithmetic coder works:
  An arithmetic coder simply lets you skew how much disk space you spend for a 0 or a 1 bit
  Respectively.  If you are sure that the next bit will be zero, you want to set the probability
  Of a zero very high, so that the weight will favor zeros over ones.

  An article going in depth on how an arithmetic coder is implemented is here
  http://www.drdobbs.com/cpp/data-compression-with-arithmetic-encodin/240169251
  But for simplicity, we'll treat the VP8 bool_decoder as a black box.

  Note that the algorithm will always produce correct results:
  The ZERO data with incorrect probability example shows the calamity that happens
  When the wrong probability is guessed for a stream. The result is simpy 7x bigger
  The data is still recoverable, just extra disk space was wasted

  Likewise you can see when the probability is guessed exactly, the compression factor is 100:1 here

  The EXERCISE is as follows: given an array filled with mostly 1 bits, what should the probability
  of a zero be passed in as.  The current value, 255, is not beneficial and results in a 6.5x
  bloat to the original file

 */
Lesson 0 - Basic Arithmetic Coding
This lesson shows how an arithmetic coder works:
An arithmetic coder simply lets you skew how much disk space you spend for a 0 or a 1 bit
Respectively.  If you are sure that the next bit will be zero, you want to set the probability
Of a zero very high, so that the weight will favor zeros over ones.



Note that the algorithm will always produce correct results:
The ZERO data with incorrect probability example shows the calamity that happens
When the wrong probability is guessed for a stream. The result is simpy 7x bigger
The data is still recoverable, just extra disk space was wasted

Likewise you can see when the probability is guessed exactly, the compression factor is 100:1 here

The EXERCISE is as follows: given an array filled with mostly 1 bits, what should the probability
of a zero be passed in as.  The current value, 255, is not beneficial and results in a 6.5x
bloat to the original file
Lesson 0 - Basic Arithmetic Coding This lesson shows how an arithmetic coder works : An arithmetic coder simply lets you skew how much disk space you spend for a 0 or a 1 bit Respectively . If you are sure that the next bit will be zero you want to set the probability Of a zero very high so that the weight will favor zeros over ones . Note that the algorithm will always produce correct results : The ZERO data with incorrect probability example shows the calamity that happens When the wrong probability is guessed for a stream . The result is simpy 7x bigger The data is still recoverable just extra disk space was wasted Likewise you can see when the probability is guessed exactly the compression factor is 100 : 1 here The EXERCISE is as follows : given an array filled with mostly 1 bits what should the probability of a zero be passed in as . The current value 255 is not beneficial and results in a 6 . 5x bloat to the original file
void encode_with_fixed_probability(uint8_t prob){
    vpx_writer wri ={0};
    vpx_start_encode(&wri, compressed); 
    for (size_t i = 0; i < sizeof(uncompressed); ++i) { 
        for(int bit = 1; bit < 256; bit <<= 1) { 
            vpx_write(&wri, !!(uncompressed[i] & bit), prob); 
        }
    }
    vpx_stop_encode(&wri);
    printf("Buffer encoded with prob(0) = %.2f results in %d size (%.2f%%)\n",
           prob / 255.,
           wri.pos,
           100 * wri.pos / float(sizeof(uncompressed)));
    vpx_reader rea={0};
    vpx_reader_init(&rea,
                    wri.buffer,
                    wri.pos); 
    memset(roundtrip, 0, sizeof(roundtrip)); 
    for (size_t i = 0; i < sizeof(roundtrip); ++i) { 
        for(int bit = 1; bit < 256; bit <<= 1) { 
            if (vpx_read(&rea, prob)) { 
                roundtrip[i] |= bit;    
            }
        }
    }
    assert(vpx_reader_has_error(&rea) == 0); 
    assert(memcmp(uncompressed, roundtrip, sizeof(uncompressed)) == 0); 
}
void encode_with_fixed_probability ( uint8_t prob ) { vpx_writer wri = { 0 } ; vpx_start_encode ( & wri , compressed ) ; for ( size_t i = 0 ; i < sizeof ( uncompressed ) ; ++ i ) { for ( int bit = 1 ; bit < 256 ; bit <<= 1 ) { vpx_write ( & wri , ! ! ( uncompressed [ i ] & bit ) , prob ) ; } } vpx_stop_encode ( & wri ) ; printf ( " \n " , prob / 255. , wri . pos , 100 * wri . pos / float ( sizeof ( uncompressed ) ) ) ; vpx_reader rea = { 0 } ; vpx_reader_init ( & rea , wri . buffer , wri . pos ) ; memset ( roundtrip , 0 , sizeof ( roundtrip ) ) ; for ( size_t i = 0 ; i < sizeof ( roundtrip ) ; ++ i ) { for ( int bit = 1 ; bit < 256 ; bit <<= 1 ) { if ( vpx_read ( & rea , prob ) ) { roundtrip [ i ] |= bit ; } } } assert ( vpx_reader_has_error ( & rea ) == 0 ) ; assert ( memcmp ( uncompressed , roundtrip , sizeof ( uncompressed ) ) == 0 ) ; }
Lesson 0 - Basic Arithmetic Coding
This lesson shows how an arithmetic coder works:
An arithmetic coder simply lets you skew how much disk space you spend for a 0 or a 1 bit
Respectively.
Lesson 0 - Basic Arithmetic Coding This lesson shows how an arithmetic coder works : An arithmetic coder simply lets you skew how much disk space you spend for a 0 or a 1 bit Respectively .
//setup the arithmetic coder // go through each byte in the buffer // for each bit in each byte // serialize out the bit // use the specified prob // to skew the cost of 1 or 0 // setup the decoder // zero out the roundtrip array // go through each byte in the output // for each bit in the output // read the bit in the input, weighted by prob // if it's true, set the bit in the output //make sure the reader has no error // make sure input = output