This commit is contained in:
parent
21357f2fb5
commit
35180f6379
7 changed files with 175 additions and 77 deletions
|
@ -7,7 +7,8 @@ lib_LTLIBRARIES = libeyd.la
|
||||||
libeyd_la_SOURCES = eyd_bitreader.cpp \
|
libeyd_la_SOURCES = eyd_bitreader.cpp \
|
||||||
eyd_bitwriter.cpp \
|
eyd_bitwriter.cpp \
|
||||||
eyd_bitgroup.cpp \
|
eyd_bitgroup.cpp \
|
||||||
eyd_compressor.cpp
|
eyd_compressor.cpp \
|
||||||
|
eyd_uncompressor.cpp
|
||||||
|
|
||||||
libeyd_la_CFLAGS = -DTRACE
|
libeyd_la_CFLAGS = -DTRACE
|
||||||
#-static
|
#-static
|
||||||
|
|
|
@ -22,6 +22,7 @@ namespace EydLib {
|
||||||
|
|
||||||
BitCompressor::BitCompressor(int size) : _rle(size) {
|
BitCompressor::BitCompressor(int size) : _rle(size) {
|
||||||
_group_size = size;
|
_group_size = size;
|
||||||
|
_last_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BitCompressor::clear(){
|
void BitCompressor::clear(){
|
||||||
|
@ -33,6 +34,8 @@ namespace EydLib {
|
||||||
void BitCompressor::flushRleData(){
|
void BitCompressor::flushRleData(){
|
||||||
BitGroup len(_group_size);
|
BitGroup len(_group_size);
|
||||||
_compressed.push_back(_rle);
|
_compressed.push_back(_rle);
|
||||||
|
printf("Last count %d\n", _last_count);
|
||||||
|
printf("Max cellsize %d\n", len.maxValue());
|
||||||
len.setValue(_last_count);
|
len.setValue(_last_count);
|
||||||
_compressed.push_back(len);
|
_compressed.push_back(len);
|
||||||
_compressed.push_back(_last_group);
|
_compressed.push_back(_last_group);
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include "eyd_bitreader.hh"
|
#include "eyd_bitreader.hh"
|
||||||
#include "eyd_bitwriter.hh"
|
#include "eyd_bitwriter.hh"
|
||||||
#include "eyd_compressor.hh"
|
#include "eyd_compressor.hh"
|
||||||
|
#include "eyd_uncompressor.hh"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
102
src/lib/eyd_uncompressor.cpp
Normal file
102
src/lib/eyd_uncompressor.cpp
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
|
||||||
|
#include "eyd_uncompressor.hh"
|
||||||
|
|
||||||
|
namespace EydLib {
|
||||||
|
|
||||||
|
/*
|
||||||
|
class BitUncompressor {
|
||||||
|
private:
|
||||||
|
BitGroup _last_group;
|
||||||
|
int _last_count;
|
||||||
|
std::list<BitGroup> _uncompressed;
|
||||||
|
|
||||||
|
public:
|
||||||
|
BitUncompressor();
|
||||||
|
|
||||||
|
void clear();
|
||||||
|
void append(BitGroup bg);
|
||||||
|
std::list<BitGroup> 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<BitGroup> BitUncompressor::flush(){
|
||||||
|
// we add the data from _last* to the outlist
|
||||||
|
std::list<BitGroup> result;
|
||||||
|
result = _uncompressed;
|
||||||
|
_uncompressed.clear();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BitUncompressor::hasContent(){
|
||||||
|
return (!_uncompressed.empty());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
41
src/lib/eyd_uncompressor.hh
Normal file
41
src/lib/eyd_uncompressor.hh
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
#ifndef _EYD_BITUNCOMPRESSOR_HH
|
||||||
|
#define _EYD_BITUNCOMPRESSOR_HH
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <exception>
|
||||||
|
|
||||||
|
#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<BitGroup> _uncompressed;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
BitUncompressor::BitUncompressor(int size);
|
||||||
|
|
||||||
|
void clear();
|
||||||
|
void append(BitGroup bg);
|
||||||
|
std::list<BitGroup> flush();
|
||||||
|
bool hasContent();
|
||||||
|
|
||||||
|
void flushRleData();
|
||||||
|
void flushRawData();
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
SUBDIRS = .
|
SUBDIRS = .
|
||||||
|
|
||||||
bin_PROGRAMS = eyd bittest bitcopy bitcompress
|
bin_PROGRAMS = eyd bittest bitcopy bitcompress bitdecompress
|
||||||
|
|
||||||
eyd_SOURCES = eyd_console.cpp eyd_init.cpp
|
eyd_SOURCES = eyd_console.cpp eyd_init.cpp
|
||||||
eyd_LDADD = -leyd
|
eyd_LDADD = -leyd
|
||||||
|
@ -33,6 +33,10 @@ bitcopy_SOURCES = bitcopy.cpp
|
||||||
bitcopy_LDADD = -leyd
|
bitcopy_LDADD = -leyd
|
||||||
bitcopy_LDFLAGS = @LDFLAGS@ -L../lib -L../lib/.libs
|
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_SOURCES = bitcompress.cpp
|
||||||
bitcompress_LDADD = -leyd
|
bitcompress_LDADD = -leyd
|
||||||
bitcompress_LDFLAGS = @LDFLAGS@ -L../lib -L../lib/.libs
|
bitcompress_LDFLAGS = @LDFLAGS@ -L../lib -L../lib/.libs
|
||||||
|
|
|
@ -9,7 +9,7 @@ void usage(){
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char ** argv){
|
int main(int argc, char ** argv){
|
||||||
EydLib::BitGroup bg;
|
EydLib::BitGroup data;
|
||||||
int cell_size;
|
int cell_size;
|
||||||
std::string original;
|
std::string original;
|
||||||
std::string copy;
|
std::string copy;
|
||||||
|
@ -23,98 +23,44 @@ int main(int argc, char ** argv){
|
||||||
EydLib::BitReader bitread(cell_size, 256);
|
EydLib::BitReader bitread(cell_size, 256);
|
||||||
bitread.open(original);
|
bitread.open(original);
|
||||||
|
|
||||||
|
unsigned char c;
|
||||||
|
bitread.readDirect(&c, 1);
|
||||||
|
//TODO: fixer cell_size en fonction de "c";
|
||||||
|
|
||||||
EydLib::BitWriter bitwrite(cell_size,256);
|
EydLib::BitWriter bitwrite(cell_size,256);
|
||||||
bitwrite.open(copy);
|
bitwrite.open(copy);
|
||||||
|
|
||||||
EydLib::BitGroup rleBg(cell_size);
|
EydLib::BitUncompressor uncompressor(cell_size);
|
||||||
EydLib::BitGroup lenBg(cell_size);
|
|
||||||
|
|
||||||
printf("Maximum value of cell : %d\n",lenBg.maxValue());
|
|
||||||
printf("File opened\n");
|
printf("File opened\n");
|
||||||
|
|
||||||
bool done=false;
|
bool done=false;
|
||||||
std::vector<EydLib::BitGroup> record;
|
std::vector<EydLib::BitGroup> record;
|
||||||
while(!done){
|
while(!done){
|
||||||
try{
|
try{
|
||||||
bg = bitread.read();
|
data = bitread.read();
|
||||||
printf("%s ",bg.toString().c_str());
|
uncompressor.append(data);
|
||||||
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;
|
|
||||||
|
|
||||||
tmpBg = record.back();
|
if (uncompressor.hasContent()){
|
||||||
// si le caractère est différent de celui d'avant
|
std::list<EydLib::BitGroup> uncompressedData = uncompressor.flush();
|
||||||
if (tmpBg != bg){
|
std::list<EydLib::BitGroup>::iterator uncmpDataIt;
|
||||||
// on compte le nombre d'éléments
|
for(uncmpDataIt = uncompressedData.begin();
|
||||||
// on pose un marqueur
|
uncmpDataIt != uncompressedData.end();
|
||||||
if (record.size()<3){
|
uncmpDataIt++){
|
||||||
// FIXME: dans le cas de cellules "0" ?
|
bitwrite.write((*uncmpDataIt)); // cellule
|
||||||
// on ecrit les cellules telles quelles...
|
|
||||||
// si la taille est incompressible
|
|
||||||
for (int i=0; i<record.size(); i++){
|
|
||||||
oldBg = record[i];
|
|
||||||
if (oldBg.getValue() == 0){
|
|
||||||
// on échape le caractere avec un RLE
|
|
||||||
bitwrite.write(rleBg); // echapement
|
|
||||||
fprintf(stderr,"RLE ");
|
|
||||||
}
|
|
||||||
bitwrite.write(oldBg);
|
|
||||||
fprintf(stderr,"%s ",oldBg.toString().c_str());
|
|
||||||
}
|
|
||||||
record.clear();
|
|
||||||
} else {
|
|
||||||
// la cellule courante est différente de l'ancienne
|
|
||||||
// et la taille est compressible
|
|
||||||
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 {
|
|
||||||
// on ne fait rien car le caractère est le meme qu'avant
|
|
||||||
// sauf si la longueur est > 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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
record.push_back(bg);
|
|
||||||
//bitwrite.write(bg);
|
|
||||||
} catch (EydLib::eBitReaderEndOfFile& e) {
|
} catch (EydLib::eBitReaderEndOfFile& e) {
|
||||||
done = true;
|
done = true;
|
||||||
// TODO: on flushe le contenu de record
|
// on flushe le contenu de record
|
||||||
|
uncompressor.flushRleData();
|
||||||
|
std::list<EydLib::BitGroup> uncompressedData = uncompressor.flush();
|
||||||
|
|
||||||
} catch (std::exception& e){
|
} catch (std::exception& e){
|
||||||
printf("ERROR\n");
|
printf("ERROR\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
printf("compression done\n");
|
printf("uncompression done\n");
|
||||||
|
|
||||||
bitread.close();
|
bitread.close();
|
||||||
bitwrite.close();
|
bitwrite.close();
|
||||||
|
|
Loading…
Reference in a new issue