diff --git a/src/lib/eyd_compressor.cpp b/src/lib/eyd_compressor.cpp index 2756367..e576b91 100644 --- a/src/lib/eyd_compressor.cpp +++ b/src/lib/eyd_compressor.cpp @@ -20,7 +20,8 @@ namespace EydLib { }; */ - BitCompressor::BitCompressor(){ + BitCompressor::BitCompressor(int size) : _rle(size) { + _group_size = size; } void BitCompressor::clear(){ @@ -30,7 +31,7 @@ namespace EydLib { } void BitCompressor::flushRleData(){ - BitGroup len; + BitGroup len(_group_size); _compressed.push_back(_rle); len.setValue(_last_count); _compressed.push_back(len); @@ -41,7 +42,10 @@ namespace EydLib { void BitCompressor::flushRawData(){ int i; for (i=0; i<_last_count; i++){ - // FIXME: on duplique les RLE trouvés + // on duplique les RLE trouvés + if (_last_group == _rle) { + _compressed.push_back(_last_group); + } _compressed.push_back(_last_group); } _last_count = 0; @@ -68,6 +72,10 @@ namespace EydLib { } } else { // nothing to do... wait for another different data... + // maybe the count is bigger than the len-cell can store ? + if (_last_count >= _rle.maxValue()){ + this->flushRleData(); + } } } else { // it is the first bitgroup diff --git a/src/lib/eyd_compressor.hh b/src/lib/eyd_compressor.hh index 88a430c..0276a56 100644 --- a/src/lib/eyd_compressor.hh +++ b/src/lib/eyd_compressor.hh @@ -22,8 +22,6 @@ namespace EydLib { int _last_count; std::list _compressed; - void flushRleData(); - void flushRawData(); public: BitCompressor(); @@ -32,6 +30,10 @@ namespace EydLib { void append(BitGroup bg); std::list flush(); bool hasContent(); + + void flushRleData(); + void flushRawData(); + }; } diff --git a/src/lib/eyd_proto.hh b/src/lib/eyd_proto.hh index 36a8894..0ba6a7d 100644 --- a/src/lib/eyd_proto.hh +++ b/src/lib/eyd_proto.hh @@ -11,6 +11,7 @@ #include "eyd_bitgroup.hh" #include "eyd_bitreader.hh" #include "eyd_bitwriter.hh" +#include "eyd_compressor.hh" #endif diff --git a/src/tools/bitcompress.cpp b/src/tools/bitcompress.cpp index 9931cb3..f846c56 100644 --- a/src/tools/bitcompress.cpp +++ b/src/tools/bitcompress.cpp @@ -9,7 +9,7 @@ void usage(){ } int main(int argc, char ** argv){ - EydLib::BitGroup bg; + EydLib::BitGroup data; int cell_size; std::string original; std::string copy; @@ -28,93 +28,32 @@ int main(int argc, char ** argv){ unsigned char c = (unsigned char)cell_size; bitwrite.writeDirect(&c, 1); - EydLib::BitGroup rleBg(cell_size); - EydLib::BitGroup lenBg(cell_size); + EydLib::BitCompressor compressor; - printf("Maximum value of cell : %d\n",lenBg.maxValue()); printf("File opened\n"); bool done=false; std::vector record; while(!done){ try{ - bg = bitread.read(); - printf("%s ",bg.toString().c_str()); - fflush(stdout); - // on pousse le bit sur dans la file - if (record.size() == 0){ - // on attend la suite... - } else { - EydLib::BitGroup tmpBg; - EydLib::BitGroup oldBg; + data = bitread.read(); + compressor.append(data); - tmpBg = record.back(); - // si le caractère est différent de celui d'avant - if (tmpBg != bg){ - // on compte le nombre d'éléments - // on pose un marqueur - oldBg = record.back(); - if (record.size()<4) { - // soit c'est uniquement des RLE - // soit c'est autre chose... - // FIXME: dans le cas de cellules "0" ? - // on ecrit les cellules telles quelles... - // si la taille est incompressible - for (int i=0; i a celle "enregistrable" - // par une cellule de donnée - if (record.size() >= rleBg.maxValue()){ - // on flushe artificiellement - bitwrite.write(rleBg); // echapement - fprintf(stderr,"\nRLE "); - lenBg.setValue(record.size()); - bitwrite.write(lenBg); // longueur - fprintf(stderr,"%s ",lenBg.toString().c_str()); - - // on a pas besoind d'échaper le caractere avec un RLE - // parce qu'il est reconnaissable (2 places apres un RLE) - bitwrite.write(tmpBg); // cellule - fprintf(stderr,"%s ",tmpBg.toString().c_str()); - // TODO: penser a calculer le taux de compression - record.clear(); - } else { - // sinon on ne fait rien, on a encore de la marge - } + if (compressor.hasContent()){ + std::list compressedData = compressor.flush(); + std::list::iterator cmpDataIt; + for(cmpDataIt = compressedData.begin(); + cmpDataIt != compressedData.end(); + cmpDataIt++){ + bitwrite.write((*cmpDataIt)); // cellule } - } - record.push_back(bg); - //bitwrite.write(bg); } catch (EydLib::eBitReaderEndOfFile& e) { done = true; // TODO: on flushe le contenu de record + compressor.flushRleData(); + std::list compressedData = compressor.flush(); + } catch (std::exception& e){ printf("ERROR\n"); }