Well, the Huffman contest just sort of floundered, so I've decided to go ahead and release the implementation I've been working on.
So basically, it's just templated version of the algorithm that works on iterators, the only real requirement being that the input data appears as a stream of bytes (the output is treated the same).
I'd love to hear your opinions/criticisms.
Test program:
Code:
#include <iostream>
#include <fstream>
#include <vector>
#include <iterator>
#include <cassert>
#include <ctime>
#include <iomanip>
#include "huffman.hpp"
using namespace
std;
typedef xtd::compression::huffman< size_t >
encoder_t;
encoder_t
encoder;
enum encoding_mode_t
{
compress,
decompress
};
void process( vector< char >& pre_processed, vector< char >& post_processed, encoding_mode_t mode )
{
clock_t
start,
stop;
post_processed.clear( );
start = clock( );
if( mode == compress )
encoder.compress( pre_processed.begin( ), pre_processed.end( ), back_inserter( post_processed ) );
else
encoder.decompress( pre_processed.begin( ), pre_processed.end( ), back_inserter( post_processed ) );
stop = clock( );
double
result = double( stop - start ) / CLK_TCK;
cout << pre_processed.size( ) << " bytes processed in " << result << " seconds" << endl;
}
int main( int argc, char** argv )
{
vector< char >
uncompressed,
compressed,
decompressed;
cout << "Huffman Test" << endl;
if( argc == 1 )
{
cout << "Usage: " << *argv << " <FILES>" << endl;
return 1;
}
while( *( ++argv ) )
{
char const*
filename = *argv;
ifstream
in( filename, ios::binary );
if( !in )
{
cerr << "Error: cannot process file '" << filename << "'" << endl;
continue;
}
cout << "File: '" << filename << "'" << endl;
cout << "...reading file..." << endl;
uncompressed.clear( );
char
ch;
while( in.read( &ch, 1 ) )
uncompressed.push_back( ch );
if( in.bad( ) )
{
cerr << "Error: could not read file '" << filename << "'" << endl;
continue;
}
cout << "Uncompressed size: " << uncompressed.size( ) << endl;
cout << "...compressing..." << endl;
process( uncompressed, compressed, compress );
double
ratio = ( double( compressed.size( ) ) / uncompressed.size( ) ) * 100;
cout << "Compressed size: " << compressed.size( )
<< " (" << setprecision( 2 ) << ratio << "%)" << endl;
cout << "...decompressing..." << endl;
process( compressed, decompressed, decompress );
cout << "...verifying..." << endl;
bool
passed = ( uncompressed == decompressed );
cout << "Result: " << ( passed ? "pass" : "fail" ) << endl;
}
return 0;
}