summaryrefslogtreecommitdiffstats
path: root/labb6
diff options
context:
space:
mode:
authorGustav Sörnäs <gustav@sornas.net>2020-12-02 08:06:39 +0100
committerGustav Sörnäs <gustav@sornas.net>2020-12-02 08:06:39 +0100
commitbf6fa300d6109966c2cb2d8bad5a4e4c15e35213 (patch)
tree4e765983159929c728873531dd0858ecca07cd35 /labb6
parentc293d85721e58915c8f901a38fbffb536518da1b (diff)
downloadtddd86-bf6fa300d6109966c2cb2d8bad5a4e4c15e35213.tar.gz
function comments
Diffstat (limited to 'labb6')
-rwxr-xr-xlabb6/src/encoding.cpp54
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()) {