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 }