#include "pibytearray.h" int PIHuffman::nodeCompare(const void * f, const void * s) { return (reinterpret_cast(const_cast(s))->freq - reinterpret_cast(const_cast(f))->freq); } PIVector PIHuffman::compress(const PIVector & src) { calcFrequencies(src); return src; } void PIHuffman::calcFrequencies(const PIVector & src) { nodes.resize(256); for (uint i = 0; i < 256; ++i) { nodes[i].parent = nodes[i].right = nodes[i].left = 0; nodes[i].freq = 0; nodes[i].word.resize(1); nodes[i].word[0] = static_cast(i); } for (uint i = 0; i < src.size(); ++i) nodes[src[i]].freq++; std::qsort(nodes.data(), 256, sizeof(node), nodeCompare); for (uint i = 255; i >= 0; --i) if (nodes[i].freq > 0 && i < 255) {nodes.remove(i + 1, 255 - i); break;} for (uint i = 0; i < nodes.size(); ++i) cout << string((char*)nodes[i].word.data(), 1) << ": " << nodes[i].freq << endl; } PIHuffman PIByteArray::huffman; PIByteArray & PIByteArray::convertToBase64() { base64HelpStruct hs; PIByteArray t; if (size() == 0) return *this; uint sz = (size() / 3) * 3; for (uint i = 0; i < sz; ++i) { hs.byte0 = hs.byte1 = hs.byte2 = 0; hs.byte0 = at(i); hs.byte1 = at(++i); hs.byte2 = at(++i); t.push_back(base64Table[hs.ascii0]); t.push_back(base64Table[hs.ascii1]); t.push_back(base64Table[hs.ascii2]); t.push_back(base64Table[hs.ascii3]); } hs.byte0 = hs.byte1 = hs.byte2 = 0; sz = size() % 3; switch (sz) { case 1: hs.byte0 = back(); t.push_back(base64Table[hs.ascii0]); t.push_back(base64Table[hs.ascii1]); t.push_back('='); t.push_back('='); break; case 2: hs.byte0 = at(size() - 2); hs.byte1 = back(); t.push_back(base64Table[hs.ascii0]); t.push_back(base64Table[hs.ascii1]); t.push_back(base64Table[hs.ascii2]); t.push_back('='); break; default: break; } *this = t; return *this; } PIByteArray & PIByteArray::convertFromBase64() { base64HelpStruct hs; PIByteArray t; uint sz = size(); if (sz == 0) return *this; for (uint i = 0; i < sz; ++i) { hs.byte0 = hs.byte1 = hs.byte2 = 0; hs.ascii0 = base64InvTable[at(i)]; hs.ascii1 = base64InvTable[at(++i)]; hs.ascii2 = base64InvTable[at(++i)]; hs.ascii3 = base64InvTable[at(++i)]; t.push_back(hs.byte0); t.push_back(hs.byte1); t.push_back(hs.byte2); } if (back() == '=') t.pop_back(); if (sz > 1) if (at(sz - 2) == '=') t.pop_back(); *this = t; return *this; } PIByteArray & PIByteArray::compressRLE(uchar threshold) { PIByteArray t; uchar fb, clen, mlen = 255 - threshold; for (uint i = 0; i < size();) { fb = at(i); clen = 1; while (at(++i) == fb) { ++clen; if (clen == mlen) break; } if (clen > 1) { t.push_back(threshold + clen); t.push_back(fb); continue; } if (fb >= threshold) { t.push_back(threshold + 1); t.push_back(fb); } else t.push_back(fb); } *this = t; return *this; } PIByteArray & PIByteArray::decompressRLE(uchar threshold) { PIByteArray t; uchar fb, clen; for (uint i = 0; i < size(); ++i) { fb = at(i); if (fb >= threshold) { clen = fb - threshold; fb = at(++i); for (uint j = 0; j < clen; ++j) t.push_back(fb); continue; } else t.push_back(fb); } *this = t; return *this; }