// // dechuf.cpp // // (c) Copyright 2000 William A. McKee. All rights reserved. // // Created April 29, 2000 // // Decompress a Huffman encoded file. (see enchuf.cpp) // // Compiled with MS VC++ 6.0: cl /Ox /GX dechuf.cpp // #include #include #include #include "huffman.h" using namespace std; static int input_count = 0; static int output_count = 0; inline unsigned char GetChar (ifstream & inf) { char ch; inf.read (&ch, 1); if (inf.eof ()) throw __LINE__; input_count ++; return static_cast(ch); } int obc = 8; unsigned char och = 0; inline int GetBit (ifstream & inf) { if (obc == 8) { och = GetChar (inf); obc = 0; } return (och>>(7-obc++))&1; } int main (int argc, char * * argv) { if (argc < 3) { cerr << "usage: dechuf " << endl; return EXIT_FAILURE; } ifstream inf (argv [1], ios::in | ios::binary); if (inf.fail ()) { cerr << "error : unable to open input file '" << argv [1] << "'." << endl; return EXIT_FAILURE; } ofstream outf (argv [2], ios::out | ios::binary); if (outf.fail ()) { cerr << "error : unable to open output file '" << argv [2] << "'." << endl; return EXIT_FAILURE; } clock_t start_time = clock (); int cnt; try { cnt = GetChar (inf) + 1; } catch (int line) { cnt = 0; } if (cnt > 0) try { struct { int code; int size; } data [257]; int j = 0; data [j].code = -1; data [j].size = GetChar (inf); j ++; int i; for (i = 0; i < cnt; i++) { data [j].code = GetChar (inf); data [j].size = GetChar (inf); j ++; } Node * root = NULL; for (i = 0; i < j; i++) { Node * * curr = & root; for (int k = 0; k < data [i].size; k++) { if (*curr == NULL) *curr = new Interior (NULL, NULL); if (GetBit (inf)) curr = & (*curr) -> Right (); else curr = & (*curr) -> Left (); } if (*curr != NULL) throw __LINE__; *curr = new Leaf (0, data [i].code); } if (root == NULL) throw __LINE__; if (root -> IsLeaf ()) throw __LINE__; Node * node = root; for (;;) { if (GetBit (inf)) node = node -> Right (); else node = node -> Left (); if (node == NULL) throw __LINE__; if (node -> IsLeaf ()) { int code = node -> Code (); if (code == -1) break; char ch = code; outf.write (&ch, 1); output_count ++; node = root; } } } catch (int line) { cerr << "error ("<