0

zlibライブラリの圧縮および解凍機能がどのように機能するかを(助けを借りて...)理解した後、私は現在、deflateおよびinflateがどのように機能するかを理解しようとしています。私が理解している限り、compressは1回の呼び出しで使用されますが、deflateは複数回呼び出すことができます。

パーティクル構造体(座標x、y、z)を使用した単純なプログラムを使用すると、エラーなしでデータをデフレートし(Z_STREAM_END応答を取得)、別のz_streamオブジェクト(Z_STREAM_END応答も)でデータをインフレートできます。しかし、膨張応答からデータを表示しようとすると、構造体のx座標とy座標を、3番目の座標(z)ではなく取得できます。

これは、膨らませるために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ループで作成された2番目のパーティクルのデータを復元できると思いましたが、取得できません。

助けてくれてありがとう!

4

1 に答える 1

2

strmInflate.avail_in = sizeof(Particle);strmInflate.avail_in = spaceUsed; deflateによって生成されたすべてのデータをinflateに提供する必要があります。

最後に、ではなく、Z_STREAM_ENDから取得したい。それ以外の場合は、生成されたストリーム全体を解凍していません。inflate()Z_OK

zlib.hのドキュメントに従って、呼び出す前にnext_inとを設定する必要があることに注意してくださいavail_in(必要Z_NULLに応じて)0inflateInit()

最終的なアプリケーションで使用する入力バッファーと出力バッファーのサイズによっては、それを保証してジョブを終了できるようにするために、さらに多くのループが必要になる場合がありdeflate()ますinflate()zlibの使用方法の例を参照してください。

于 2012-11-26T18:50:21.253 に答える