lzw_decoder.tpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00030 #include <list>
00031
00032
00038 template<typename InputBuffer, typename OutputBuffer>
00039 void claw::lzw_decoder<InputBuffer, OutputBuffer>::decode
00040 ( input_buffer_type& input, output_buffer_type& output )
00041 {
00042 const unsigned int symbols_count = input.symbols_count();
00043
00044 table_type table;
00045 unsigned int table_size = 0;
00046
00047 unsigned int prefix = input.get_next();
00048
00049 if ( !input.end_of_data() )
00050 {
00051 while ( !input.end_of_data() )
00052 {
00053 unsigned int suffix = input.get_next();
00054
00055 if (!input.end_of_data() )
00056 {
00057 unsigned int new_suffix;
00058
00059 if ( suffix < table_size + symbols_count )
00060 new_suffix = get_first_symbol(table, suffix, symbols_count);
00061 else
00062 new_suffix = get_first_symbol(table, prefix, symbols_count);
00063
00064 table.push_back( word_type(prefix, new_suffix) );
00065 ++table_size;
00066 input.new_code(table_size + symbols_count);
00067
00068 decompose( table, prefix, symbols_count, output );
00069 prefix = suffix;
00070 }
00071 }
00072
00073 decompose( table, prefix, symbols_count, output );
00074 }
00075 }
00076
00077
00084 template<typename InputBuffer, typename OutputBuffer>
00085 unsigned int claw::lzw_decoder<InputBuffer, OutputBuffer>::get_first_symbol
00086 ( const table_type& table, const unsigned int code,
00087 const unsigned int symbols_count ) const
00088 {
00089 unsigned int result = code;
00090
00091 while ( result >= symbols_count )
00092 result = table[result - symbols_count].first;
00093
00094 return result;
00095 }
00096
00097
00105 template<typename InputBuffer, typename OutputBuffer>
00106 void claw::lzw_decoder<InputBuffer, OutputBuffer>::decompose
00107 ( const table_type& table, unsigned int code,
00108 const unsigned int symbols_count, output_buffer_type& output ) const
00109 {
00110 std::list<unsigned int> result;
00111
00112 while ( code >= symbols_count )
00113 {
00114 result.push_front( table[code - symbols_count].second );
00115 code = table[code - symbols_count].first;
00116 }
00117
00118 result.push_front(code);
00119
00120 std::list<unsigned int>::const_iterator it;
00121
00122 for (it=result.begin(); it!=result.end(); ++it)
00123 output.write( *it );
00124
00125 }