From 35180f6379ed0521434b36f9c2f0cf5db1664aad Mon Sep 17 00:00:00 2001 From: glenux Date: Sun, 30 Oct 2005 20:56:05 +0000 Subject: [PATCH] --- src/lib/Makefile.am | 3 +- src/lib/eyd_compressor.cpp | 3 ++ src/lib/eyd_proto.hh | 1 + src/lib/eyd_uncompressor.cpp | 102 +++++++++++++++++++++++++++++++++++ src/lib/eyd_uncompressor.hh | 41 ++++++++++++++ src/tools/Makefile.am | 6 ++- src/tools/bitdecompress.cpp | 96 ++++++++------------------------- 7 files changed, 175 insertions(+), 77 deletions(-) create mode 100644 src/lib/eyd_uncompressor.cpp create mode 100644 src/lib/eyd_uncompressor.hh diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 86b86b1..d7d821a 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -7,7 +7,8 @@ lib_LTLIBRARIES = libeyd.la libeyd_la_SOURCES = eyd_bitreader.cpp \ eyd_bitwriter.cpp \ eyd_bitgroup.cpp \ - eyd_compressor.cpp + eyd_compressor.cpp \ + eyd_uncompressor.cpp libeyd_la_CFLAGS = -DTRACE #-static diff --git a/src/lib/eyd_compressor.cpp b/src/lib/eyd_compressor.cpp index e576b91..043aa10 100644 --- a/src/lib/eyd_compressor.cpp +++ b/src/lib/eyd_compressor.cpp @@ -22,6 +22,7 @@ namespace EydLib { BitCompressor::BitCompressor(int size) : _rle(size) { _group_size = size; + _last_count = 0; } void BitCompressor::clear(){ @@ -33,6 +34,8 @@ namespace EydLib { void BitCompressor::flushRleData(){ BitGroup len(_group_size); _compressed.push_back(_rle); + printf("Last count %d\n", _last_count); + printf("Max cellsize %d\n", len.maxValue()); len.setValue(_last_count); _compressed.push_back(len); _compressed.push_back(_last_group); diff --git a/src/lib/eyd_proto.hh b/src/lib/eyd_proto.hh index 0ba6a7d..a2e5868 100644 --- a/src/lib/eyd_proto.hh +++ b/src/lib/eyd_proto.hh @@ -12,6 +12,7 @@ #include "eyd_bitreader.hh" #include "eyd_bitwriter.hh" #include "eyd_compressor.hh" +#include "eyd_uncompressor.hh" #endif diff --git a/src/lib/eyd_uncompressor.cpp b/src/lib/eyd_uncompressor.cpp new file mode 100644 index 0000000..cc8823c --- /dev/null +++ b/src/lib/eyd_uncompressor.cpp @@ -0,0 +1,102 @@ + +#include "eyd_uncompressor.hh" + +namespace EydLib { + + /* + class BitUncompressor { + private: + BitGroup _last_group; + int _last_count; + std::list _uncompressed; + + public: + BitUncompressor(); + + void clear(); + void append(BitGroup bg); + std::list flush(); + bool hasContent(); + }; + */ + + BitUncompressor::BitUncompressor(int size) : _rle(size) { + _group_size = size; + _last_count = 0; + } + + void BitUncompressor::clear(){ + // we clear everything + _last_count = 0; + _uncompressed.clear(); + } + + void BitUncompressor::flushRleData(){ + BitGroup len(_group_size); + _uncompressed.push_back(_rle); + printf("Last count %d\n", _last_count); + printf("Max cellsize %d\n", len.maxValue()); + len.setValue(_last_count); + _uncompressed.push_back(len); + _uncompressed.push_back(_last_group); + _last_count = 0; + } + + void BitUncompressor::flushRawData(){ + int i; + for (i=0; i<_last_count; i++){ + // on duplique les RLE trouvés + if (_last_group == _rle) { + _uncompressed.push_back(_last_group); + } + _uncompressed.push_back(_last_group); + } + _last_count = 0; + } + + void BitUncompressor::append(BitGroup data){ + // take the data and make it smaller... + if (_last_count > 0) { + // there are data in the compressor + if (data != _last_group){ + // we have to empty the compressed list + if (_last_count < 4){ + // not efficient + if ((_last_count > 1) && (_last_group == _rle)) { + // 1 RLE gives 2 RLE + // 2 RLE gives 4 RLE... let compress it... + this->flushRleData(); + } else { + this->flushRawData(); + } + } else { + // efficient ! lets compress it ! + this->flushRleData(); + } + } 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 + } + _last_group = data; + _last_count++; + } + + std::list BitUncompressor::flush(){ + // we add the data from _last* to the outlist + std::list result; + result = _uncompressed; + _uncompressed.clear(); + return result; + } + + bool BitUncompressor::hasContent(){ + return (!_uncompressed.empty()); + } +} + diff --git a/src/lib/eyd_uncompressor.hh b/src/lib/eyd_uncompressor.hh new file mode 100644 index 0000000..079409d --- /dev/null +++ b/src/lib/eyd_uncompressor.hh @@ -0,0 +1,41 @@ +#ifndef _EYD_BITUNCOMPRESSOR_HH +#define _EYD_BITUNCOMPRESSOR_HH + +#include +#include +#include +#include +#include + +#include "eyd_bitgroup.hh" + +#include "eyd_global.hh" +#include "eyd_iface.hh" + + +namespace EydLib { + + class BitUncompressor { + private: + BitGroup _rle; + BitGroup _last_group; + int _last_count; + int _group_size; + std::list _uncompressed; + + + public: + BitUncompressor::BitUncompressor(int size); + + void clear(); + void append(BitGroup bg); + std::list flush(); + bool hasContent(); + + void flushRleData(); + void flushRawData(); + + }; +} + +#endif diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am index c660973..e599ea9 100644 --- a/src/tools/Makefile.am +++ b/src/tools/Makefile.am @@ -2,7 +2,7 @@ SUBDIRS = . -bin_PROGRAMS = eyd bittest bitcopy bitcompress +bin_PROGRAMS = eyd bittest bitcopy bitcompress bitdecompress eyd_SOURCES = eyd_console.cpp eyd_init.cpp eyd_LDADD = -leyd @@ -33,6 +33,10 @@ bitcopy_SOURCES = bitcopy.cpp bitcopy_LDADD = -leyd bitcopy_LDFLAGS = @LDFLAGS@ -L../lib -L../lib/.libs +bitdecompress_SOURCES = bitdecompress.cpp +bitdecompress_LDADD = -leyd +bitdecompress_LDFLAGS = @LDFLAGS@ -L../lib -L../lib/.libs + bitcompress_SOURCES = bitcompress.cpp bitcompress_LDADD = -leyd bitcompress_LDFLAGS = @LDFLAGS@ -L../lib -L../lib/.libs diff --git a/src/tools/bitdecompress.cpp b/src/tools/bitdecompress.cpp index ccfb3df..1d96d84 100644 --- a/src/tools/bitdecompress.cpp +++ b/src/tools/bitdecompress.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; @@ -22,99 +22,45 @@ int main(int argc, char ** argv){ EydLib::BitReader bitread(cell_size, 256); bitread.open(original); - + + unsigned char c; + bitread.readDirect(&c, 1); + //TODO: fixer cell_size en fonction de "c"; + EydLib::BitWriter bitwrite(cell_size,256); bitwrite.open(copy); - EydLib::BitGroup rleBg(cell_size); - EydLib::BitGroup lenBg(cell_size); + EydLib::BitUncompressor uncompressor(cell_size); - 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(); + uncompressor.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 - if (record.size()<3){ - // 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,"RLE "); - 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 (uncompressor.hasContent()){ + std::list uncompressedData = uncompressor.flush(); + std::list::iterator uncmpDataIt; + for(uncmpDataIt = uncompressedData.begin(); + uncmpDataIt != uncompressedData.end(); + uncmpDataIt++){ + bitwrite.write((*uncmpDataIt)); // cellule } - } - record.push_back(bg); - //bitwrite.write(bg); } catch (EydLib::eBitReaderEndOfFile& e) { done = true; - // TODO: on flushe le contenu de record + // on flushe le contenu de record + uncompressor.flushRleData(); + std::list uncompressedData = uncompressor.flush(); + } catch (std::exception& e){ printf("ERROR\n"); } } - printf("compression done\n"); + printf("uncompression done\n"); bitread.close(); bitwrite.close();