Initial fixed huffman coding for png.

This commit is contained in:
James Grogan 2022-11-28 10:16:04 +00:00
parent e4f9393ee7
commit 7f5009fb5e
39 changed files with 1294 additions and 440 deletions

View file

@ -0,0 +1,100 @@
#include "HuffmanEncoder.h"
#include "RawTree.h"
#include <unordered_map>
#include <queue>
#include <tuple>
#include <iostream>
void HuffmanEncoder::dumpNode(RawNode<CountPair>* node, unsigned depth) const
{
if (!node)
{
return;
}
auto data = node->getData();
std::string prefix(depth, '_');
if (node->isLeaf())
{
std::cout << prefix << "Leaf with value: " << data.first << " and sum " << data.second << std::endl;
}
else
{
std::cout << prefix << "Intermediate with sum " << data.second << std::endl;
std::cout << prefix << "Doing Left.." << std::endl;
dumpNode(node->getLeftChild(), depth+1);
std::cout << prefix << "Doing Right.." << std::endl;
dumpNode(node->getRightChild(), depth+1);
std::cout << prefix << "*****" << std::endl;
}
}
void HuffmanEncoder::dumpTree(const RawTree<CountPair>& tree) const
{
dumpNode(tree.getRootNode(), 0);
}
void HuffmanEncoder::encode(const HuffmanEncoder::DataStream& stream)
{
std::unordered_map<unsigned char, unsigned> counts;
for (auto c : stream)
{
counts[c]++;
}
encode(counts);
}
void HuffmanEncoder::encode(const std::unordered_map<unsigned char, unsigned>& counts)
{
std::cout << "Counts" << std::endl;
for (const auto& data: counts)
{
std::cout << data.first << " | " << data.second << std::endl;
}
std::cout << "*******" << std::endl;
auto cmp = [](RawNode<CountPair>* left, RawNode<CountPair>* right)
{
return left->getData().second > right->getData().second;
};
std::priority_queue<RawNode<CountPair>*, std::vector<RawNode<CountPair>* >, decltype(cmp)> q(cmp);
for (const auto& entry : counts)
{
q.push(new RawNode<CountPair>(entry));
}
while(q.size() > 1)
{
auto node0 = q.top();
q.pop();
auto node1 = q.top();
q.pop();
const auto sum = node0->getData().second + node1->getData().second;
auto new_node = new RawNode<CountPair>(CountPair{0, sum});
new_node->addChild(node0);
new_node->addChild(node1);
q.push(new_node);
}
auto root = q.top();
q.pop();
RawTree<CountPair> tree;
tree.addRootNode(root);
//using TableEntry = std::tuple<>
dumpTree(tree);
std::cout << "********" << std::endl;
}