gpt4 book ai didi

C++ zilib deflate/inflate 和 ztream 参数

转载 作者:行者123 更新时间:2023-11-28 03:27:20 26 4
gpt4 key购买 nike

在了解(借助一些帮助...)zlib 库的压缩和解压缩功能如何工作之后,我现在正试图了解放气和膨胀的工作方式。据我了解,compress 用于一次调用,而 deflate 可以多次调用。

有一个带有粒子结构(坐标 x、y、z)的简单程序,我可以无误地缩小我的数据(获得 Z_STREAM_END 响应),然后用另一个 z_stream 对象(也有 Z_STREAM_END 响应)将它们膨胀。但是当我试图从膨胀响应中显示我的数据时,我可以通过不是第三个 (z) 获得我的结构的 x 和 y 坐标。

我认为这是由于我为我的 z_stream 对象提供了一个错误的膨胀参数,但我找不到哪个参数。据我了解阅读文档和示例,这就是我认为 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 循环中创建的第二个粒子的数据,但我无法检索它。

在此先感谢您的帮助!

最佳答案

strmInflate.avail_in = sizeof(Particle);需要是 strmInflate.avail_in = spaceUsed;您必须提供由 deflate 产生的所有数据。

最后你想得到Z_STREAM_END来自 inflate() , 不是 Z_OK .否则你还没有解压缩整个生成的流。

请注意,根据 zlib.h 中的文档, 你还需要设置 next_inavail_in (到 Z_NULL0 如果你愿意的话)在调用 inflateInit() 之前

根据您将在最终应用程序中使用的输入和输出缓冲区的大小,您可能需要更多循环来确保 deflate()inflate()可以完成他们的工作。请参阅example of how to use zlib .

关于C++ zilib deflate/inflate 和 ztream 参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13569545/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com