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;
    }

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

          

  • 相关阅读:
    out/host/linuxx86/obj/EXECUTABLES/aapt_intermediates/aapt 64 32 操作系统
    linux 查看路由器 电脑主机 端口号 占用
    linux proc进程 pid stat statm status id 目录 解析 内存使用
    linux vim 设置大全详解
    ubuntu subclipse svn no libsvnjavahl1 in java.library.path no svnjavahl1 in java.library.path no s
    win7 安装 ubuntu 双系统 详解 easybcd 工具 不能进入 ubuntu 界面
    Atitit.json xml 序列化循环引用解决方案json
    Atitit.编程语言and 自然语言的比较and 编程语言未来的发展
    Atitit.跨语言  文件夹与文件的io操作集合  草案
    Atitit.atijson 类库的新特性设计与实现 v3 q31
  • 原文地址:https://www.cnblogs.com/wangchenggen/p/3602293.html
Copyright © 2011-2022 走看看