сжатие — параметры C ++ zilib deflate / inflate и ztream

После того, как я понял (с некоторой помощью …), как работают функции сжатия и распаковки библиотеки zlib, я теперь пытаюсь понять, как работают deflate и inflate. Насколько я понимаю, compress используется в одном вызове, тогда как deflate может вызываться несколько раз.

Имея простую программу со структурой частиц (координаты x, y, z), я могу без ошибок выкачивать свои данные (получая ответ Z_STREAM_END), а затем раздувать их другим объектом z_stream (тоже ответ Z_STREAM_END). Но когда я попытался отобразить мои данные из ответа на инфляцию, я могу получить координаты x и y моей структуры, а не третью (z).

Я думаю, что это из-за неправильных параметров, которые я дал моему объекту z_stream для inflate, но я не могу найти какой. Насколько я понимаю, читая документы и пример, я думаю, что z_stream работает (это только пример):

// Here i give a total memory size for the output buffer used by deflate func
#define CHUNK 16384

struct Particle
{
float x;
float y;
float z;
};

...

// An element to get a single particule and give it to deflate func
Bytef *dataOriginal = (Bytef*)malloc( sizeof(Particle) );

// This var will be used to pass compressed data
Bytef *dataCompressed = (Bytef*)malloc( CHUNK );

z_stream strm;
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
deflateInit(&strm, Z_DEFAULT_COMPRESSION);

strm.avail_out = CHUNK;
strm.next_out = dataCompressed;

int nbrLoop = 2;
int spaceUsed = 0;
int flush;
Particle p;

for (var i = 0; i<nbrLoop; i++){
// set all values equals to 0
memset( &p, 0, sizeof(Particle) );

// insert some random values
p.x = (i+1) * 1;
p.y = (i+1) * 3;
p.z = (i+1) * 7;

//copy this values in a Bytef* elements
memcpy( dataOriginal, &p, sizeof(Particle) );strm.avail_in = sizeof(dataOriginal);
strm.next_in = dataOriginal;

// If it's the last particle :
if(i == nbrLoop - 1){
flush = Z_FINISH;
}
else{
flush = Z_NO_FLUSH;
}

int response = deflate(&strm, flush);

// I don't get any errors here
// EDIT : Get Z_OK at first loop, the Z_STREAM_END at second (last)
if( res == Z_STREAM_END ){
spaceUsed = CHUNK - strm.avail_out;
}
}

deflateEnd(&strm);

// Trying to get back my datas
Bytef *decomp = (Bytef*)malloc( sizeof(Particle) );

z_stream strmInflate;
strmInflate.zalloc = Z_NULL;
strmInflate.zfree = Z_NULL;
strmInflate.opaque = Z_NULL;
inflateInit(&strmInflate);

// datas i want to get at the next inflate
strmInflate.avail_in = sizeof(Particle);
strmInflate.next_in = dataCompressed;

// Two particles were compressed, so i need to get back two
strmInflate.avail_out = sizeof(Particle) * 2;
strmInflate.next_out = decomp;

int response = inflate( &strmInflate, Z_NO_FLUSH );
// No error here,
// EDIT : Get Z_OK

inflateEnd( &strmInflate );

Particle testP;
memset( &testP, 0, sizeof(Particle) );
memcpy( &testP, decomp, sizeof(Particle) );

std::cout << testP.x << std::endl; // display 1 OK
std::cout << testP.y << std::endl; // display 3 OK
std::cout << testP.z << std::endl; // display 0 NOT OK

Более того, я думал, что вызов inflate во второй раз позволит мне восстановить данные моей второй частицы, которая была создана в моем цикле for, но я не могу получить ее.

Заранее благодарю за любую помощь !

0

Решение

strmInflate.avail_in = sizeof(Particle); должно быть strmInflate.avail_in = spaceUsed; Вы должны предоставить inflate все данные, полученные с помощью deflate.

В конце вы хотите получить Z_STREAM_END от inflate()не Z_OK, В противном случае вы не распаковали весь сгенерированный поток.

Обратите внимание, что согласно документации в zlib.h, вам также нужно установить next_in а также avail_inZ_NULL а также 0 если хотите) перед звонком inflateInit()

В зависимости от размера входного и выходного буферов, которые вы будете использовать в конечном приложении, вам может потребоваться больше циклов, чтобы deflate() а также inflate() может закончить свою работу. Пожалуйста, смотрите пример использования zlib.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]