zoukankan      html  css  js  c++  java
  • LZMA压缩解压

           这里介绍的是如何使用开源的LZMA压缩解压算法库。

           下载地址:http://tukaani.org/xz/

           里面有头文件、动态库和文档。里面有例子程序,是压缩和解压文件的,我试用过,可以。我这里介绍压缩buff到另一个buff中,这样可以实现边接受来自网络的数据,边写压缩文件。

          

    #include "stdafx.h"
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <errno.h>
    #include <assert.h>
    
    #define LZMA_API_STATIC
    #include "lzma.h"
    
    #define LZMA_PRESET_VAL 0
    
    static uint32_t
    get_preset()
    {
        return LZMA_PRESET_VAL | LZMA_PRESET_EXTREME;
    }
    
    
    static bool
    get_error(lzma_ret ret)
    {
        // Return successfully if the initialization went fine.
        if (ret == LZMA_OK | LZMA_STREAM_END)
            return true;
    
        // Something went wrong. The possible errors are documented in
        // lzma/container.h (src/liblzma/api/lzma/container.h in the source
        // package or e.g. /usr/include/lzma/container.h depending on the
        // install prefix).
        const char *msg;
        switch (ret) {
        case LZMA_MEM_ERROR:
            msg = "Memory allocation failed";
            break;
    
        case LZMA_OPTIONS_ERROR:
            msg = "Specified preset is not supported";
            break;
    
        case LZMA_UNSUPPORTED_CHECK:
            msg = "Specified integrity check is not supported";
            break;
    
        default:
            // This is most likely LZMA_PROG_ERROR indicating a bug in
            // this program or in liblzma. It is inconvenient to have a
            // separate error message for errors that should be impossible
            // to occur, but knowing the error code is important for
            // debugging. That's why it is good to print the error code
            // at least when there is no good error message to show.
            msg = "Unknown error, possibly a bug";
            break;
        }
    
        fprintf(stderr, "Error initializing the encoder: %s (error code %u)
    ",
                msg, ret);
        return false;
    }
    
    static bool
    init_encoder(lzma_stream *strm, uint32_t preset)
    {
        // Initialize the encoder using a preset. Set the integrity to check
        // to CRC64, which is the default in the xz command line tool. If
        // the .xz file needs to be decompressed with XZ Embedded, use
        // LZMA_CHECK_CRC32 instead.
        lzma_ret ret = lzma_easy_encoder(strm, preset, LZMA_CHECK_CRC64);
    
        return get_error(ret);
    }
    
    static bool
    init_decoder(lzma_stream *strm)
    {
        // Initialize a .xz decoder. The decoder supports a memory usage limit
        // and a set of flags.
        //
        // The memory usage of the decompressor depends on the settings used
        // to compress a .xz file. It can vary from less than a megabyte to
        // a few gigabytes, but in practice (at least for now) it rarely
        // exceeds 65 MiB because that's how much memory is required to
        // decompress files created with "xz -9". Settings requiring more
        // memory take extra effort to use and don't (at least for now)
        // provide significantly better compression in most cases.
        //
        // Memory usage limit is useful if it is important that the
        // decompressor won't consume gigabytes of memory. The need
        // for limiting depends on the application. In this example,
        // no memory usage limiting is used. This is done by setting
        // the limit to UINT64_MAX.
        //
        // The .xz format allows concatenating compressed files as is:
        //
        //     echo foo | xz > foobar.xz
        //     echo bar | xz >> foobar.xz
        //
        // When decompressing normal standalone .xz files, LZMA_CONCATENATED
        // should always be used to support decompression of concatenated
        // .xz files. If LZMA_CONCATENATED isn't used, the decoder will stop
        // after the first .xz stream. This can be useful when .xz data has
        // been embedded inside another file format.
        //
        // Flags other than LZMA_CONCATENATED are supported too, and can
        // be combined with bitwise-or. See lzma/container.h
        // (src/liblzma/api/lzma/container.h in the source package or e.g.
        // /usr/include/lzma/container.h depending on the install prefix)
        // for details.
        lzma_ret ret = lzma_stream_decoder(
                strm, UINT64_MAX, LZMA_CONCATENATED);
    
        return get_error(ret);
    }
    
    static bool
    do_lzma_code(lzma_stream *strm, const unsigned char *in_buff,const int in_size, unsigned char *out_buff, int & out_size)
    {
        lzma_action action = LZMA_FINISH;
    
        uint8_t outbuf[BUFSIZ];
    
        strm->next_out = outbuf;
        strm->avail_out = sizeof(outbuf);
    
        strm->next_in = in_buff;
        strm->avail_in = in_size;
    
        lzma_ret ret = lzma_code(strm, action);
    
        out_size = sizeof(outbuf) - strm->avail_out;
        memcpy(out_buff,outbuf,out_size);
    
        return get_error(ret);
    }
    
    void 
    wang_compress(const unsigned char *in_buff,const int in_size, unsigned char *out_buff, int & out_size)
    {
        uint32_t preset = get_preset();
        lzma_stream strm = LZMA_STREAM_INIT;
    
        bool success = init_encoder(&strm, preset);
        if (success)
        {
            success = do_lzma_code(&strm, in_buff,in_size,out_buff, out_size);
        }
    
        lzma_end(&strm);
    }
    void 
    wang_decompress(const unsigned char *in_buff,const int in_size, unsigned char *out_buff, int & out_size)
    {
        lzma_stream strm = LZMA_STREAM_INIT;
        bool success = true;
    
        if (!init_decoder(&strm)) {
                // Decoder initialization failed. There's no point
                // to retry it so we need to exit.
            success = false;
        }
    
        success &= do_lzma_code(&strm,in_buff,in_size,out_buff,out_size);
    
        lzma_end(&strm);
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        const unsigned char  const_string_value[] = "wjfsjfsjfojsofjsojrhghfgehoiheighehgehgieghhgohg osjfi`, sk;f;'l";
    
        std::cout<<const_string_value<<std::endl;
    
        const int const_string_size = strlen((const char*)const_string_value);
    
        std::cout<<const_string_size<<std::endl;
    
        unsigned char buff[1024] = {0};
    
        int size = 0;
    
        wang_compress(const_string_value,const_string_size,buff,size);
    
    
        std::cout<<size<<std::endl;
    
        unsigned char out_string_value[1024]={0};
        int out_string_size = 0;
    
        wang_decompress(buff,size,out_string_value,out_string_size);
    
        assert(out_string_size == const_string_size);
    
        std::cout<<out_string_value<<std::endl;
        std::cout<<const_string_size<<std::endl;
    
        std::cin>>out_string_size;
    }

            最后测试程序证明,可以。

          

  • 相关阅读:
    Locust:简介和基本用法
    linux more less 用法
    Pytest测试用例之setup与teardown方法
    app测试之monkey
    理解yield以及和return的区别
    Python 数据驱动工具:DDT
    requests 使用 proxies 代理时ValueError: check_hostname requires server_hostname
    from urllib.parse import urlparse 使用
    linux 三剑客 使用总结 grep sed awk
    企查查和天眼查哪个好用
  • 原文地址:https://www.cnblogs.com/wangchenggen/p/3602293.html
Copyright © 2011-2022 走看看