This commit is contained in:
glenux 2005-10-31 17:54:08 +00:00
parent 5b5de22d2e
commit 6e71b527b8
11 changed files with 119 additions and 118 deletions

View file

@ -1,3 +1,3 @@
SUBDIRS = lib rle1 rle2 SUBDIRS = lib rle1 rle2 tests
#rleGolomb #rleGolomb

View file

@ -3,41 +3,37 @@
namespace EydLib { namespace EydLib {
/*
class BitCompressorRle1 {
private:
BitGroup _last_group;
int _last_count;
std::list<BitGroup> _compressed;
public:
BitCompressorRle1();
void clear();
void append(BitGroup bg);
std::list<BitGroup> flush();
bool hasContent();
};
*/
BitCompressorRle1::BitCompressorRle1(int size) : _rle(size) { BitCompressorRle1::BitCompressorRle1(int size) : _rle(size) {
_group_size = size; _group_size = size;
_last_count = 0; _last_count = 0;
_input_size = 0;
_output_size = 0;
} }
void BitCompressorRle1::clear(){ void BitCompressorRle1::clear(){
// we clear everything // we clear everything
_last_count = 0; _last_count = 0;
_compressed.clear(); _compressed.clear();
_input_size = 0;
_output_size = 0;
} }
void BitCompressorRle1::flushRleData(){ void BitCompressorRle1::flushRleData(){
BitGroup len(_group_size); BitGroup len(_group_size);
_output_size += _rle.size();
_compressed.push_back(_rle); _compressed.push_back(_rle);
printf("Last count %d\n", _last_count); printf("Last count %d\n", _last_count);
printf("Max cellsize %d\n", len.maxValue()); printf("Max cellsize %d\n", len.maxValue());
len.setValue(_last_count); len.setValue(_last_count);
_output_size += len.size();
_compressed.push_back(len); _compressed.push_back(len);
_output_size += _last_group.size();
_compressed.push_back(_last_group); _compressed.push_back(_last_group);
_last_count = 0; _last_count = 0;
} }
@ -47,14 +43,17 @@ namespace EydLib {
for (i=0; i<_last_count; i++){ for (i=0; i<_last_count; i++){
// on duplique les RLE trouvés // on duplique les RLE trouvés
if (_last_group == _rle) { if (_last_group == _rle) {
_output_size += _last_group.size();
_compressed.push_back(_last_group); _compressed.push_back(_last_group);
} }
_output_size += _last_group.size();
_compressed.push_back(_last_group); _compressed.push_back(_last_group);
} }
_last_count = 0; _last_count = 0;
} }
void BitCompressorRle1::append(BitGroup data){ void BitCompressorRle1::append(BitGroup data){
_input_size += data.size();
// take the data and make it smaller... // take the data and make it smaller...
if (_last_count > 0) { if (_last_count > 0) {
// there are data in the compressor // there are data in the compressor
@ -98,5 +97,11 @@ namespace EydLib {
bool BitCompressorRle1::hasContent(){ bool BitCompressorRle1::hasContent(){
return (!_compressed.empty()); return (!_compressed.empty());
} }
float BitCompressorRle1::getRatio(){
float ratio = 1000* (float)_output_size / (float)_input_size;
int ratio2 = (int)ratio;
return (((float)ratio2) / 10.0);
}
} }

View file

@ -21,6 +21,8 @@ namespace EydLib {
BitGroup _last_group; BitGroup _last_group;
int _last_count; int _last_count;
int _group_size; int _group_size;
unsigned long int _input_size;
unsigned long int _output_size;
std::list<BitGroup> _compressed; std::list<BitGroup> _compressed;
@ -34,7 +36,7 @@ namespace EydLib {
void flushRleData(); void flushRleData();
void flushRawData(); void flushRawData();
float getRatio();
}; };
} }

View file

@ -3,48 +3,55 @@
namespace EydLib { namespace EydLib {
/*
class BitCompressorRle2 {
private:
int _last_count;
std::list<BitGroup> _compressed;
public:
BitCompressorRle2();
void clear();
void append(BitGroup bg);
std::list<BitGroup> flush();
bool hasContent();
};
*/
BitCompressorRle2::BitCompressorRle2(int size) : _rle(size) { BitCompressorRle2::BitCompressorRle2(int size) : _rle(size) {
// la taille des donnees enregistrees dépend de size
_last_count = 0; _last_count = 0;
_compressed.clear(); _compressed.clear();
_input_size = 0;
_output_size = 0;
} }
void BitCompressorRle2::clear(){ void BitCompressorRle2::clear(){
// we clear everything // we clear everything
_last_count = 0; _last_count = 0;
_compressed.clear(); _compressed.clear();
_input_size = 0;
_output_size = 0;
}
void BitCompressorRle2::forceFlush(){
if (_last_count > 0){
printf(" -> flushing %d",_last_count);
BitGroup result(_rle.size());
result.setValue(_last_count);
printf("(=> %s)\n",result.toString().c_str());
_compressed.push_back(result);
_output_size += result.size();
} else {
printf(" -> no flush %d\n",_last_count);
}
} }
void BitCompressorRle2::appendBit(bool bit){ void BitCompressorRle2::appendBit(bool bit){
printf("%d",bit);
fflush(stdout);
if (!bit){ if (!bit){
_last_count++; _last_count++;
} else { } else {
printf(" -> flushing %d",_last_count);
// on écrit _last_count sur la sortie // on écrit _last_count sur la sortie
if (_last_count > 0){ BitGroup result(_rle.size());
BitGroup result(_rle.size()); result.setValue(_last_count);
result.setValue(_last_count); printf("(=> %s)\n",result.toString().c_str());
_compressed.push_back(result); _compressed.push_back(result);
} _output_size += result.size();
_last_count=0; _last_count=0;
} }
} }
void BitCompressorRle2::append(BitGroup data){ void BitCompressorRle2::append(BitGroup data){
_input_size += data.size();
// take the data and make it smaller... // take the data and make it smaller...
// foreach bit of data, append it... // foreach bit of data, append it...
for (int i=0; i<data.size(); i++){ for (int i=0; i<data.size(); i++){
@ -63,5 +70,12 @@ namespace EydLib {
bool BitCompressorRle2::hasContent(){ bool BitCompressorRle2::hasContent(){
return (!_compressed.empty()); return (!_compressed.empty());
} }
float BitCompressorRle2::getRatio(){
float ratio = 1000 * (float)_output_size / (float)_input_size;
int ratio2 = (int)ratio;
return (((float)ratio2) / 10.0);
}
} }

View file

@ -20,20 +20,23 @@ namespace EydLib {
BitGroup _rle; BitGroup _rle;
int _last_count; int _last_count;
int _group_size; int _group_size;
unsigned long int _input_size;
unsigned long int _output_size;
std::list<BitGroup> _compressed; std::list<BitGroup> _compressed;
void BitCompressorRle2::appendBit(bool bit); void BitCompressorRle2::appendBit(bool bit);
public: public:
BitCompressorRle2::BitCompressorRle2(); BitCompressorRle2::BitCompressorRle2(int size);
void clear(); void clear();
void append(BitGroup bg); void append(BitGroup bg);
std::list<BitGroup> flush(); std::list<BitGroup> flush();
bool hasContent(); bool hasContent();
void flushRleData(); void forceFlush();
void flushRawData(); float getRatio();
}; };
} }

View file

@ -3,72 +3,53 @@
namespace EydLib { namespace EydLib {
/* BitUncompressorRle2::BitUncompressorRle2(int size) : _wrk_grp(size) {
class BitUncompressorRle2 { _group_size = size;
private:
BitGroup _last_group;
int _last_count;
std::list<BitGroup> _uncompressed;
public:
BitUncompressorRle2();
void clear();
void append(BitGroup bg);
std::list<BitGroup> flush();
bool hasContent();
};
*/
BitUncompressorRle2::BitUncompressorRle2() {
_last_count = 0; _last_count = 0;
_status = UNCOMPRESSOR_RLE2_STATUS_NORMAL; _first_group = true;
_wrk_pos = 0;
} }
void BitUncompressorRle2::clear(){ void BitUncompressorRle2::clear(){
// we clear everything // we clear everything
_last_count = 0; _last_count = 0;
_uncompressed.clear(); _uncompressed.clear();
_first_group = true;
_wrk_pos = 0;
}
void BitUncompressorRle2::appendBit(bool bit){
_wrk_grp.setBitAt(_wrk_pos, bit);
printf(" (buf= %s, pos= %d) ",_wrk_grp.toString().c_str(),_wrk_pos);
_wrk_pos++;
if (_wrk_pos >= _wrk_grp.size()){
_uncompressed.push_back(_wrk_grp);
BitGroup clr(_wrk_grp.size());
_wrk_grp = clr;
_wrk_pos = 0;
}
} }
void BitUncompressorRle2::append(BitGroup data){ void BitUncompressorRle2::append(BitGroup data){
switch (_status){ printf("got %d -> expanding ",data.getValue());
case UNCOMPRESSOR_RLE2_STATUS_NORMAL: BitGroup out(1);
printf("STATUS NORMAL : %s\n", data.toString().c_str()); if (_first_group){
if (data == _rle){ // X zéros sans 1 apres
// on change le status et on n'écrit rien for (int i=0; i<data.getValue(); i++){
_status = UNCOMPRESSOR_RLE2_STATUS_GOTRLE; this->appendBit(false);
} else { printf("0");
// on écrit directement le resultat non décompressé }
_uncompressed.push_back(data); _first_group = false;
} } else {
break; // 1 suivi de X zeros
case UNCOMPRESSOR_RLE2_STATUS_GOTRLE: printf("1");
printf("STATUS GOT RLE : %s\n", data.toString().c_str() ); this->appendBit(true);
if (data == _rle){ for (int i=0; i<data.getValue(); i++){
// deux RLE c'est 1 RLE this->appendBit(false);
// on écrit juste un RLE printf("0");
_uncompressed.push_back(data); }
_status = UNCOMPRESSOR_RLE2_STATUS_NORMAL;
} else {
// un RLE et un différent c'est une longueur
// sauf si égal à 1 ou 2
_status = UNCOMPRESSOR_RLE2_STATUS_GOTLEN; // sauf si égal à RLE
_last_count = data.getValue(); // on stocke la value
}
break;
case UNCOMPRESSOR_RLE2_STATUS_GOTLEN:
printf("STATUS GOT LEN : %s\n", data.toString().c_str() );
// ce qu'on lit est la valeur
// on écrit donc _last_count fois data
for (int i=0; i<_last_count; i++){
_uncompressed.push_back(data);
}
_status = UNCOMPRESSOR_RLE2_STATUS_NORMAL;
_last_count = 0;
break;
} }
printf("\n");
} }
std::list<BitGroup> BitUncompressorRle2::flush(){ std::list<BitGroup> BitUncompressorRle2::flush(){

View file

@ -14,22 +14,19 @@
namespace EydLib { namespace EydLib {
typedef enum {
UNCOMPRESSOR_RLE2_STATUS_NORMAL,
UNCOMPRESSOR_RLE2_STATUS_GOTLEN,
UNCOMPRESSOR_RLE2_STATUS_GOTRLE}
uncompressorRle2_status_t;
class BitUncompressorRle2 { class BitUncompressorRle2 {
private: private:
BitGroup _rle; BitGroup _wrk_grp;
int _last_count; int _last_count;
int _wrk_pos;
int _group_size; int _group_size;
std::list<BitGroup> _uncompressed; std::list<BitGroup> _uncompressed;
uncompressorRle2_status_t _status; bool _first_group;
void appendBit(bool bit);
public: public:
BitUncompressorRle2::BitUncompressorRle2(); BitUncompressorRle2::BitUncompressorRle2(int size);
void clear(); void clear();
void append(BitGroup bg); void append(BitGroup bg);

View file

@ -53,5 +53,6 @@ namespace EydTools {
bitwrite.close(); bitwrite.close();
printf("file closed\n"); printf("file closed\n");
printf("Compression ratio : %f\n", compressorRle1.getRatio());
} }
} }

View file

@ -4,7 +4,7 @@ namespace EydTools {
void EydRle2::compress(){ void EydRle2::compress(){
EydLib::BitGroup data; EydLib::BitGroup data;
EydLib::BitReader bitread(_cellsize, 256); EydLib::BitReader bitread(_cellsize, 256); // on lit bit à bit expres
bitread.open(_input_file); bitread.open(_input_file);
EydLib::BitWriter bitwrite(_cellsize,256); EydLib::BitWriter bitwrite(_cellsize,256);
@ -12,7 +12,7 @@ namespace EydTools {
unsigned char c = (unsigned char)_cellsize; unsigned char c = (unsigned char)_cellsize;
bitwrite.writeDirect(&c, 1); bitwrite.writeDirect(&c, 1);
EydLib::BitCompressorRle2 compressor; EydLib::BitCompressorRle2 compressor(_cellsize);
printf("File opened\n"); printf("File opened\n");
@ -35,6 +35,7 @@ namespace EydTools {
} catch (EydLib::eBitReaderEndOfFile& e) { } catch (EydLib::eBitReaderEndOfFile& e) {
done = true; done = true;
// on flushe le contenu de record // on flushe le contenu de record
compressor.forceFlush();
std::list<EydLib::BitGroup> compressedData = compressor.flush(); std::list<EydLib::BitGroup> compressedData = compressor.flush();
std::list<EydLib::BitGroup>::iterator cmpDataIt; std::list<EydLib::BitGroup>::iterator cmpDataIt;
for(cmpDataIt = compressedData.begin(); for(cmpDataIt = compressedData.begin();
@ -42,8 +43,6 @@ namespace EydTools {
cmpDataIt++){ cmpDataIt++){
bitwrite.write((*cmpDataIt)); // cellule bitwrite.write((*cmpDataIt)); // cellule
} }
} catch (std::exception& e){
printf("ERROR\n");
} }
} }
printf("compression done\n"); printf("compression done\n");
@ -52,5 +51,6 @@ namespace EydTools {
bitwrite.close(); bitwrite.close();
printf("file closed\n"); printf("file closed\n");
printf("Compression ratio : %f\n", compressor.getRatio());
} }
} }

View file

@ -55,9 +55,9 @@ namespace EydTools {
if (_output_file.length() == 0){ if (_output_file.length() == 0){
if (_mode_compress == EYDRLE2_MODE_COMPRESS){ if (_mode_compress == EYDRLE2_MODE_COMPRESS){
_output_file = _input_file + ".rl1"; _output_file = _input_file + ".rl2";
} else { } else {
_output_file = _input_file + ".rl1_orig"; _output_file = _input_file + ".rl2_orig";
} }
} }

View file

@ -9,7 +9,7 @@ namespace EydTools {
unsigned char c; unsigned char c;
bitread.readDirect(&c, 1); bitread.readDirect(&c, 1);
//TODO: fixer cell_size en fonction de "c"; // doit-on fixer cell_size en fonction de "c";
if (c != _cellsize){ if (c != _cellsize){
printf("WARNING : File cellsize is %d, but uncompressing with %d\n",c, _cellsize); printf("WARNING : File cellsize is %d, but uncompressing with %d\n",c, _cellsize);
@ -18,7 +18,7 @@ namespace EydTools {
EydLib::BitWriter bitwrite(_cellsize,256); EydLib::BitWriter bitwrite(_cellsize,256);
bitwrite.open(_output_file); bitwrite.open(_output_file);
EydLib::BitUncompressorRle2 uncompressor; EydLib::BitUncompressorRle2 uncompressor(_cellsize);
printf("File opened\n"); printf("File opened\n");
@ -49,8 +49,6 @@ namespace EydTools {
uncmpDataIt++){ uncmpDataIt++){
bitwrite.write((*uncmpDataIt)); // cellule bitwrite.write((*uncmpDataIt)); // cellule
} }
} catch (std::exception& e){
printf("ERROR\n");
} }
} }
printf("uncompression done\n"); printf("uncompression done\n");