LZMA压缩库使用记录

使用原因:
使用py2,.7版本,对应有pylzma支持库,但是发现支持库对于参数设置好像不是很全面,如字典大小支持范围较小,于是重新下载自己编译调用

7Z包含的算法有:
LZMA 改良与优化后的 LZ77 算法
LZMA2 改良的 LZMA 算法
PPMD 基于 Dmitry Shkarin 的 PPMdH 算法
BCJ 32 位 x86 可执行文件转换程序
BCJ2 32 位 x86 可执行文件转换程序
BZip2 标准 BWT 算法
Deflate 标准 LZ77-based 算法

LZMA算法介绍:
LZMA是7z格式默认的压缩算法,它的主要特征有:
● 高压缩比率;
● 可变的字典大小(高达4GB);
● 压缩速度:在 2 GHz CPU上,大约 1 MB/s;
● 解压缩速度:在 2 GHz CPU上,大约10-20 MB/s ;
● 较小解压缩内存(依赖于所选的字典大小);
● 较小的解压缩代码,大约5KB;
● 支持多线程;

下载链接:
http://www.7-zip.org/sdk.html

下载后编译为对应使用平台动态库,导出LzmaLib.h中的相关加解压函数接口

MY_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen,
unsigned char outProps, size_t *outPropsSize, / outPropsSize must be = 5 /
int level, /* 0 <= level <= 9, default = 5 */
unsigned dictSize, /* default = (1 << 24) */
int lc, /* 0 <= lc <= 8, default = 3 */
int lp, /* 0 <= lp <= 4, default = 0 */
int pb, /* 0 <= pb <= 4, default = 2 */
int fb, /* 5 <= fb <= 273, default = 32 */
int numThreads /* 1 or 2, default = 2 */
);

MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, SizeT *srcLen,
const unsigned char *props, size_t propsSize);

附上简单封装调用的python脚本:

# -*-coding:utf-8-*-
from ctypes import *

class lzmaLib1604:
    SZ_OK = 0 #- OK
    SZ_ERROR_DATA = 1 #- Data error
    SZ_ERROR_MEM = 2 #- Memory allocation error
    SZ_ERROR_UNSUPPORTED = 4  #- Unsupported properties
    SZ_ERROR_PARAM = 5 #- Incorrect paramater
    SZ_ERROR_INPUT_EOF = 6 #- it needs more bytes in input buffer (src)
    SZ_ERROR_OUTPUT_EOF = 7 #- output buffer overflow
    SZ_ERROR_THREAD = 12 #- errors in multithreading functions(only for Mt version)
    LZMA_PROPS_SIZE = 5

    def __init__(self):
        self.Lzma1604LibPath = "Lzma1604"
        self.Objdll = CDLL(self.Lzma1604LibPath)

    # int LzmaCompress(unsigned char * dest, size_t * destLen, const unsigned char * src, size_t srcLen,unsigned char * outProps, size_t * outPropsSize,
    # int level, / *0 <= level <= 9, default = 5 * /
    # unsigned  dictSize, / *use(1 << N) or (3 << N).4KB < dictSize <= 128MB * /
    # int lc, / *0 <= lc <= 8, default = 3 * /
    # int lp, / *0 <= lp <= 4, default = 0 * /
    # int pb, / *0 <= pb <= 4, default = 2 * /
    # int fb, / *5 <= fb <= 273, default = 32 * /
    # int numThreads / * 1 or 2, default = 2 * /
    def LzmaCompress(self,uncompressData,uncompressLen,compressLen):
        outPropsSize = c_uint(self.LZMA_PROPS_SIZE)
        outProps = create_string_buffer('/0' * self.LZMA_PROPS_SIZE)
        level = c_int(9)
        dictSize = c_uint(1 << 24)
        lc = c_int(3)
        lp = c_int(0)
        pb = c_int(2)
        fb = c_int(32)
        numThreads = c_int(1)

        srcBuf = c_char_p()
        srcBuf.value = uncompressData
        srcBufLen = c_uint(uncompressLen)

        destBuf = create_string_buffer('/0' * compressLen)
        destLen = c_uint(compressLen)

        result = -1
        try:
            result = self.Objdll.LzmaCompress(byref(destBuf),byref(destLen),srcBuf,srcBufLen,byref(outProps),byref(outPropsSize),level,dictSize,lc,lp,pb,fb,numThreads)
        except:
            print "lzmaLib1604_LzmaCompress : compress failed."

        if result == self.SZ_OK:
            return outProps[:outPropsSize.value] + destBuf[:destLen.value]
        elif result == self.SZ_ERROR_MEM:
            print "lzmaLib1604_LzmaCompress : memory malloc failed."
        elif result == self.SZ_ERROR_PARAM:
            print "lzmaLib1604_LzmaCompress : parameters wrong."
        elif result == self.SZ_ERROR_OUTPUT_EOF:
            print "lzmaLib1604_LzmaCompress : output memory too little."
        elif result == self.SZ_ERROR_THREAD:
            print "lzmaLib1604_LzmaCompress : thread error."
        else:
            print "lzmaLib1604_LzmaCompress : unknown error."

        return ""

    def LzmaUnCompress(self,compressData,compressLen,uncompressLen):
        outPropsSize = c_uint(self.LZMA_PROPS_SIZE)
        outProps = c_char_p()
        outProps.value = compressData[:self.LZMA_PROPS_SIZE]

        srcBuf = c_char_p()
        srcBuf.value = compressData[self.LZMA_PROPS_SIZE:]
        srcBufLen = c_uint(compressLen - self.LZMA_PROPS_SIZE)

        destBuf = create_string_buffer('/0' * uncompressLen)
        destLen = c_uint(uncompressLen)

        result = -1
        try:
            result = self.Objdll.LzmaUncompress(byref(destBuf),byref(destLen),srcBuf,byref(srcBufLen),outProps,outPropsSize)
        except:
            print "lzmaLib1604_LzmaUnCompress : uncompress failed."

        if result == self.SZ_OK:
            return destBuf.raw[:uncompressLen]
        elif result == self.SZ_ERROR_MEM:
            print "lzmaLib1604_LzmaUnCompress : memory malloc failed."
        elif result == self.SZ_ERROR_DATA:
            print "lzmaLib1604_LzmaUnCompress : Data error."
        elif result == self.SZ_ERROR_UNSUPPORTED:
            print "lzmaLib1604_LzmaUnCompress : Unsupported properties."
        elif result == self.SZ_ERROR_INPUT_EOF:
            print "lzmaLib1604_LzmaUnCompress : it needs more bytes in input buffer (src)."
        else:
            print "lzmaLib1604_LzmaUnCompress : unknown error."

        return ""

参考:
http://velep.com/archives/368.html

你可能感兴趣的:(工具使用)