3 #include "nta/Compressor.h"
4 #include "nta/Logger.h"
12 for (
int i = 0; i < numBits; i++) {
13 if ((1 & (num >> i)) == 1) {
23 for (
int i = 0; i < num.size(); i++) {
32 std::map<GLubyte, int> frequencies;
33 for (
auto&
byte : data) {
34 if (frequencies.find(
byte) == frequencies.end()) {
35 frequencies[byte] = 1;
40 std::vector<HuffmanNode*> byteNodes;
41 for (
const auto& pair : frequencies) {
42 byteNodes.push_back(
new HuffmanLeaf(pair.first, pair.second));
46 while (byteNodes.size() > 1) {
47 smallestFreq = *std::min_element(byteNodes.begin(), byteNodes.end(), [](
HuffmanNode* lhs,
HuffmanNode* rhs){
48 return (lhs->getFrequency() < rhs->getFrequency());
50 std::remove(byteNodes.begin(), byteNodes.end(), smallestFreq); byteNodes.pop_back();
51 scnsmallFreq = *std::min_element(byteNodes.begin(), byteNodes.end(), [](
HuffmanNode* lhs,
HuffmanNode* rhs){
52 return (lhs->getFrequency() < rhs->getFrequency());
54 std::remove(byteNodes.begin(), byteNodes.end(), scnsmallFreq); byteNodes.pop_back();
55 byteNodes.push_back(
new HuffmanNode(smallestFreq, scnsmallFreq));
57 m_root = byteNodes.front();
64 std::string compressedBits =
"";
66 for (
const auto&
byte : data) {
68 meta = std::max<float>(meta, log2(
m_encodings[
byte].length())+1);
70 unsigned long size = compressedBits.size();
71 unsigned long numBytes = log2((
double)size)/8.+1;
72 compressedBits =
toBinary(numBytes) +
toBinary(size, 8*numBytes) + compressedBits;
73 std::string encodingInfo =
"";
75 encodingInfo +=
toBinary(pair.first) +
toBinary(pair.second.size(), meta) + pair.second;
77 size = encodingInfo.size();
78 numBytes = log2((
double)size)/8.+1;
79 compressedBits =
toBinary(numBytes) +
toBinary(size, 8*numBytes) +
toBinary(meta, 3) + encodingInfo + compressedBits;
80 size = compressedBits.size();
82 std::vector<GLubyte> compressedData;
83 for (
int i = 0; i < numBytes; i++) {
84 compressedData.push_back(
fromBinary(compressedBits.substr(i*8,8)));
86 compressedData.push_back(
fromBinary(compressedBits.substr(8*numBytes)));
88 return compressedData;
91 std::vector<GLubyte> uncompressedData;
92 std::string compressedBits =
"";
93 for (
auto&
byte : data) {
96 unsigned long bytesForSize = data.front();
97 unsigned long eInfoLen =
fromBinary(compressedBits.substr(8,8*bytesForSize));
98 int meta =
fromBinary(compressedBits.substr(8+8*bytesForSize,3));
99 std::map<std::string, GLubyte> encodings;
101 for (pos = 11+8*bytesForSize; pos < 11+8*bytesForSize+eInfoLen;) {
102 std::pair<std::string, GLubyte> curr;
103 curr.second =
fromBinary(compressedBits.substr(pos,8));
104 int codeLength =
fromBinary(compressedBits.substr(pos+8,meta));
105 curr.first = compressedBits.substr(pos+8+meta,codeLength);
106 encodings.insert(curr);
107 pos += 8+meta+codeLength;
109 bytesForSize =
fromBinary(compressedBits.substr(pos,8));
110 unsigned long cDataLen =
fromBinary(compressedBits.substr(pos+8,8*bytesForSize));
111 unsigned long eof = pos+8+8*bytesForSize+cDataLen;
112 std::string curr =
"";
113 for (pos = pos+8+8*bytesForSize; pos < eof; pos++) {
114 curr += compressedBits[pos];
115 if (encodings.find(curr) != encodings.end()) {
116 uncompressedData.push_back(encodings[curr]);
120 return uncompressedData;