diff options
| author | Gustav Sörnäs <gustav@sornas.net> | 2020-12-02 08:06:39 +0100 |
|---|---|---|
| committer | Gustav Sörnäs <gustav@sornas.net> | 2020-12-02 08:06:39 +0100 |
| commit | bf6fa300d6109966c2cb2d8bad5a4e4c15e35213 (patch) | |
| tree | 4e765983159929c728873531dd0858ecca07cd35 | |
| parent | c293d85721e58915c8f901a38fbffb536518da1b (diff) | |
| download | tddd86-bf6fa300d6109966c2cb2d8bad5a4e4c15e35213.tar.gz | |
function comments
| -rwxr-xr-x | labb6/src/encoding.cpp | 54 |
1 files changed, 52 insertions, 2 deletions
diff --git a/labb6/src/encoding.cpp b/labb6/src/encoding.cpp index a28cf6c..b5ecd4e 100755 --- a/labb6/src/encoding.cpp +++ b/labb6/src/encoding.cpp @@ -2,6 +2,10 @@ #include <queue> +/* + * Read from a input stream until EOF and return the text's frequency table, i.e. + * how many times each character was found in the text. + */ map<int, int> buildFrequencyTable(istream& input) { map<int, int> freq_table; while (true) { @@ -18,6 +22,11 @@ map<int, int> buildFrequencyTable(istream& input) { return freq_table; } +/* + * Build and return a Huffman tree from a frequency table. + * + * Remember to free the tree when you're done! + */ HuffmanNode* buildEncodingTree(const map<int, int>& freq_table) { std::priority_queue<HuffmanNode> nodes; for (const auto& freq_element : freq_table) { @@ -40,6 +49,9 @@ HuffmanNode* buildEncodingTree(const map<int, int>& freq_table) { return root; } +/* + * Merge 'from' into 'to', overwriting if a key already exists. + */ template <typename T, typename U> void merge_map(map<T, U>& into, const map<T, U>& from) { for (const auto& element : from) { @@ -62,16 +74,25 @@ map<int, string> encoding_map_helper(HuffmanNode *encoding_tree, const string& c return encoding_map; } +/* + * Build a Huffman encoding map (char -> bit-string) from a Huffman tree. + */ map<int, string> buildEncodingMap(HuffmanNode* encoding_tree) { return encoding_map_helper(encoding_tree, ""); } +/* + * Write a bit-string as bits to an obitstream. + */ void encode_char(int c, const map<int, string>& encoding_map, obitstream& output) { for (const auto& bit : encoding_map.at(c)) { output.writeBit(bit == '0' ? 0 : 1); } } +/* + * Write 'input' Huffman-compressed to 'output' encoded with 'encoding_map'. + */ void encodeData(istream& input, const map<int, string>& encoding_map, obitstream& output) { while (true) { int c = input.get(); @@ -83,6 +104,10 @@ void encodeData(istream& input, const map<int, string>& encoding_map, obitstream encode_char(PSEUDO_EOF, encoding_map, output); } +/* + * Read a single character from the Huffman-compressed 'input' encded with + * 'encoding_map'. + */ int read_char(ibitstream& input, HuffmanNode* encoding_tree) { if (encoding_tree->isLeaf()) { return encoding_tree->character; @@ -96,6 +121,10 @@ int read_char(ibitstream& input, HuffmanNode* encoding_tree) { } } +/* + * Read the Huffman-compressed 'input' encoded with 'encoding_tree' and write + * it to 'output'. + */ void decodeData(ibitstream& input, HuffmanNode* encoding_tree, ostream& output) { while (true) { int next_char = read_char(input, encoding_tree); @@ -107,7 +136,10 @@ void decodeData(ibitstream& input, HuffmanNode* encoding_tree, ostream& output) } } -void encodeHeader(const map<int, int>& freq_table, obitstream& output) { +/* + * Write 'freq_table' (char -> frequency) as a Huffman-header to 'output'. + */ +void encodeHeader(const map<int, int>& freq_table, ostream& output) { output.write("{", 1); int i = 0; for (const auto& encode : freq_table) { @@ -124,6 +156,9 @@ void encodeHeader(const map<int, int>& freq_table, obitstream& output) { output.write("}", 1); } +/* + * Huffman-compress 'input' and write it and its header to 'output'. + */ void compress(istream& input, obitstream& output) { map<int, int> freq_table = buildFrequencyTable(input); HuffmanNode* encoding_tree = buildEncodingTree(freq_table); @@ -137,7 +172,11 @@ void compress(istream& input, obitstream& output) { freeTree(encoding_tree); } -int read_int(istream& input, int *next_char = nullptr) { +/* + * Read an integer from 'input'. The char immediately following the integer + * is also read and is stored in *next_char, if it's set. + */ +int read_int(istream& input, int* next_char = nullptr) { string str; while (true) { int c = input.get(); @@ -152,6 +191,10 @@ int read_int(istream& input, int *next_char = nullptr) { } } +/* + * Read a Huffman-header from 'input'. When done, 'input' will point to + * the first non-header byte. + */ map<int, int> decodeHeader(istream& input) { map<int, int> freq_table; if (input.get() != '{') { @@ -171,6 +214,10 @@ map<int, int> decodeHeader(istream& input) { return freq_table; } +/* + * Read the Huffman-compressed 'input' (header included) and write it to + * 'output'. + */ void decompress(ibitstream& input, ostream& output) { map<int, int> freq_table = decodeHeader(input); HuffmanNode* encoding_tree = buildEncodingTree(freq_table); @@ -180,6 +227,9 @@ void decompress(ibitstream& input, ostream& output) { freeTree(encoding_tree); } +/* + * Completely free a Huffman tree. + */ void freeTree(HuffmanNode* node) { if (node) { if (!node->isLeaf()) { |
