This commit is contained in:
glenux 2005-10-30 21:42:06 +00:00
parent 35180f6379
commit aceaba7f24
4 changed files with 64 additions and 68 deletions

View file

@ -23,6 +23,7 @@ namespace EydLib {
BitUncompressor::BitUncompressor(int size) : _rle(size) { BitUncompressor::BitUncompressor(int size) : _rle(size) {
_group_size = size; _group_size = size;
_last_count = 0; _last_count = 0;
_status = UNCOMPRESSOR_STATUS_NORMAL;
} }
void BitUncompressor::clear(){ void BitUncompressor::clear(){
@ -31,60 +32,44 @@ namespace EydLib {
_uncompressed.clear(); _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){ void BitUncompressor::append(BitGroup data){
// take the data and make it smaller... switch (_status){
if (_last_count > 0) { case UNCOMPRESSOR_STATUS_NORMAL:
// there are data in the compressor printf("STATUS NORMAL : %s\n", data.toString().c_str());
if (data != _last_group){ if (data == _rle){
// we have to empty the compressed list // on change le status et on n'écrit rien
if (_last_count < 4){ _status = UNCOMPRESSOR_STATUS_GOTRLE;
// 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 { } else {
this->flushRawData(); // on écrit directement le resultat non décompressé
_uncompressed.push_back(data);
} }
break;
case UNCOMPRESSOR_STATUS_GOTRLE:
printf("STATUS GOT RLE : %s\n", data.toString().c_str() );
if (data == _rle){
// deux RLE c'est 1 RLE
// on écrit juste un RLE
_uncompressed.push_back(data);
_status = UNCOMPRESSOR_STATUS_NORMAL;
} else { } else {
// efficient ! lets compress it ! // un RLE et un différent c'est une longueur
this->flushRleData(); // sauf si égal à 1 ou 2
_status = UNCOMPRESSOR_STATUS_GOTLEN; // sauf si égal à RLE
_last_count = data.getValue(); // on stocke la value
} }
} else { break;
// nothing to do... wait for another different data... case UNCOMPRESSOR_STATUS_GOTLEN:
// maybe the count is bigger than the len-cell can store ? printf("STATUS GOT LEN : %s\n", data.toString().c_str() );
if (_last_count >= _rle.maxValue()){ // ce qu'on lit est la valeur
this->flushRleData(); // on écrit donc _last_count fois data
for (int i=0; i<_last_count; i++){
_uncompressed.push_back(data);
} }
_status = UNCOMPRESSOR_STATUS_NORMAL;
_last_count = 0;
break;
} }
} else {
// it is the first bitgroup
}
_last_group = data;
_last_count++;
} }
std::list<BitGroup> BitUncompressor::flush(){ std::list<BitGroup> BitUncompressor::flush(){

View file

@ -14,15 +14,15 @@
namespace EydLib { namespace EydLib {
typedef enum {UNCOMPRESSOR_STATUS_NORMAL, UNCOMPRESSOR_STATUS_GOTLEN, UNCOMPRESSOR_STATUS_GOTRLE} uncompressor_status_t;
class BitUncompressor { class BitUncompressor {
private: private:
BitGroup _rle; BitGroup _rle;
BitGroup _last_group;
int _last_count; int _last_count;
int _group_size; int _group_size;
std::list<BitGroup> _uncompressed; std::list<BitGroup> _uncompressed;
uncompressor_status_t _status;
public: public:
BitUncompressor::BitUncompressor(int size); BitUncompressor::BitUncompressor(int size);

View file

@ -53,7 +53,12 @@ int main(int argc, char ** argv){
// TODO: on flushe le contenu de record // TODO: on flushe le contenu de record
compressor.flushRleData(); compressor.flushRleData();
std::list<EydLib::BitGroup> compressedData = compressor.flush(); std::list<EydLib::BitGroup> compressedData = compressor.flush();
std::list<EydLib::BitGroup>::iterator cmpDataIt;
for(cmpDataIt = compressedData.begin();
cmpDataIt != compressedData.end();
cmpDataIt++){
bitwrite.write((*cmpDataIt)); // cellule
}
} catch (std::exception& e){ } catch (std::exception& e){
printf("ERROR\n"); printf("ERROR\n");
} }

View file

@ -18,7 +18,7 @@ int main(int argc, char ** argv){
cell_size = atoi(argv[1]); cell_size = atoi(argv[1]);
original = argv[2]; original = argv[2];
copy = original + ".rl1"; copy = original + ".rl2";
EydLib::BitReader bitread(cell_size, 256); EydLib::BitReader bitread(cell_size, 256);
bitread.open(original); bitread.open(original);
@ -53,9 +53,15 @@ int main(int argc, char ** argv){
} catch (EydLib::eBitReaderEndOfFile& e) { } catch (EydLib::eBitReaderEndOfFile& e) {
done = true; done = true;
// on flushe le contenu de record // on flushe le contenu de record
uncompressor.flushRleData(); // FIXME: trouver un moyen de flusher la fin du fichier
// uncompressor.flushRleData();
std::list<EydLib::BitGroup> uncompressedData = uncompressor.flush(); std::list<EydLib::BitGroup> uncompressedData = uncompressor.flush();
std::list<EydLib::BitGroup>::iterator uncmpDataIt;
for(uncmpDataIt = uncompressedData.begin();
uncmpDataIt != uncompressedData.end();
uncmpDataIt++){
bitwrite.write((*uncmpDataIt)); // cellule
}
} catch (std::exception& e){ } catch (std::exception& e){
printf("ERROR\n"); printf("ERROR\n");
} }