【问题标题】:How to use deflate/inflate SetDictionary with raw deflate/inflate?如何将 deflate/inflate SetDictionary 与原始 deflate/inflate 一起使用?
【发布时间】:2015-06-08 06:28:54
【问题描述】:

当我们使用字典时,我试图了解原始 deflate 的功能。我知道以下内容。 1. 当我们使用字典时,应用程序应该为 deflate() 和 inflate() 提供相同的字典。 2. 执行原始 deflate 时,必须在任何 deflate 调用之前调用此函数,或在 deflate 块完成后立即调用此函数,即在使用任何刷新选项时,在所有输入已被消耗且所有输出已交付之后@ 987654321@、Z_PARTIAL_FLUSHZ_SYNC_FLUSHZ_FULL_FLUSH。 (来自 zlib 文档)。

但以下应用程序无法解压缩之前使用相同应用程序压缩的内容。压缩解压成功,但输入文件与解压文件不匹配。

放气:

    do {
        ret = deflateSetDictionary(&strm, dictionary, sizeof(dictionary));
        if(ret != Z_OK) {
            fprintf(stderr, "Failed to set deflate dictionary\n");
            return Z_STREAM_ERROR;
        }
        strm.avail_in = fread(in, 1, CHUNK, source);
        if (ferror(source)) {
            (void)deflateEnd(&strm);
            return Z_ERRNO;
        }
        flush = feof(source) ? Z_FINISH : Z_FULL_FLUSH;
        strm.next_in = in;

        /* run deflate() on input until output buffer not full, finish
           compression if all of source has been read in */
        do {
            strm.avail_out = CHUNK;
            strm.next_out = out;
            ret = deflate(&strm, flush);    /* no bad return value */
            assert(ret != Z_STREAM_ERROR);  /* state not clobbered */
            have = CHUNK - strm.avail_out;
            if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
                (void)deflateEnd(&strm);
                return Z_ERRNO;
            }
        } while (strm.avail_out == 0);
        assert(strm.avail_in == 0);     /* all input will be used */

        /* done when last data in file processed */
    } while (flush != Z_FINISH);
    assert(ret == Z_STREAM_END);     

膨胀:

    do {
        ret = inflateSetDictionary(&strm, dictionary, sizeof(dictionary));
        if(ret != Z_OK) {
            fprintf(stderr, "Failed to set inflate dictionary\n");
            return Z_STREAM_ERROR;
        }
        strm.avail_in = fread(in, 1, CHUNK, source);
        if (ferror(source)) {
            (void)inflateEnd(&strm);
            return Z_ERRNO;
        }
        if (strm.avail_in == 0)
            break;
        strm.next_in = in;


        /* run inflate() on input until output buffer not full */
        do {
            strm.avail_out = CHUNK;
            strm.next_out = out;
            ret = inflate(&strm, Z_FULL_FLUSH);
            assert(ret != Z_STREAM_ERROR);  /* state not clobbered */
            switch (ret) {
            case Z_NEED_DICT:
                ret = Z_DATA_ERROR;     /* and fall through */
            case Z_DATA_ERROR:
            case Z_MEM_ERROR:
                (void)inflateEnd(&strm);
                return ret;
            }
            have = CHUNK - strm.avail_out;
            if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
                (void)inflateEnd(&strm);
                return Z_ERRNO;
            }
        } while (strm.avail_out == 0);

        /* done when inflate() says it's done */
    } while (ret != Z_STREAM_END);

【问题讨论】:

    标签: c zlib compression deflate


    【解决方案1】:

    放气时,您将在每个CHUNK 输入字节设置相同的字典。为什么?您应该在deflateInit2() 之后使用一次deflateSetDictionary()。从那时起,输入数据本身应该比您提供的字典更适合作为匹配字符串的来源。

    在膨胀方面,您必须知道压缩块的结束位置,以便您可以在压缩时完全相同的位置执行inflateSetDictionary()。这将需要某种标记、计数或搜索完整的冲洗模式。

    【讨论】:

    • 感谢您的回答。我为每个 CHUNK 输入字节调用 deflateSetdictionary() 仅用于实验目的。无论如何,我在你回答的后半部分得到了澄清。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-17
    • 1970-01-01
    • 2011-09-04
    • 1970-01-01
    • 1970-01-01
    • 2016-07-18
    相关资源
    最近更新 更多