01.03.2011 - as a initial commit

This commit is contained in:
peri4
2011-03-01 06:07:16 +03:00
parent 3610ea9212
commit b21a0496cd
20 changed files with 1589 additions and 522 deletions

140
pibytearray.cpp Normal file
View File

@@ -0,0 +1,140 @@
#include "pibytearray.h"
int PIHuffman::nodeCompare(const void * f, const void * s) {
return (reinterpret_cast<node * >(const_cast<void * >(s))->freq -
reinterpret_cast<node * >(const_cast<void * >(f))->freq);
}
PIVector<uchar> PIHuffman::compress(const PIVector<uchar> & src) {
calcFrequencies(src);
return src;
}
void PIHuffman::calcFrequencies(const PIVector<uchar> & 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<uchar>(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;
}