LZMA 介绍

LZMA 介绍

LZMA,(Lempel-Ziv-Markov chain-Algorithm的缩写),是一个Deflate和LZ77算法改良和优化后的压缩算法,开发者是Igor Pavlov,目前7zip等压缩工具都使用了LZMA压缩算法。

LZMA 的特性
  - 可变的字典大小,可达1GB。
  - 在2GHZ的CPU上压缩速率是2MB/S秒。
  - 解压速率评估
      - 在2 GHz Core 2 or AMD Athlon 64处理器上,大约是20-30MB/S
      - 在200 MHz ARM, MIPS, PowerPC or other simple RISC 上是1-2MB/S
  - 解压需要少量的内存(16 KB + DictionarySize)
  - 解压代码量很少5-8 KB

在http://www.7-zip.org/sdk.html网页上提供了LZMA的SDK开发包下载,包中的一级目录中包含了如下内容:ASM, C, Cpp, CS, Java文件夹,和7zc.txt、7zformat.txt、7zr.exe、history.txt、lzma.exe、lzma.txt、methods.txt文件。lzma.txt是重要的SDK文档,其中介绍了LZMA的目录结构和一些方法的使用,这个文档应该首先看看。我着重看了C的版本,它位于C目录下。在C/util目录下有几个目录,这几个目录中的例子演示了如何使用lzma,lzma目录中是源码使用方式,LzmaLib中是DLL使用方式。其中的代码很多是基于对文件的压缩和解压缩,我这里写了一个内存的压缩示例,把这个方法放在lzma\LzmaUtil.c文件中调用就可以.

code
 1int mytest()
 2{
 3    const int kSize = 2048;
 4    int *pInBuf = (int*)malloc(kSize * sizeof(int));
 5    int *pOutBuf = (int*)malloc((kSize) * sizeof(int));
 6    int *pInBuf2 = (int*)malloc(kSize * sizeof(int));
 7    unsigned char *outprops = (char *)malloc(5);
 8    int i = 0;
 9    CLzmaEncProps props;
10    SRes res;
11    ELzmaStatus status;
12    int nResult;
13    size_t destLen = kSize * sizeof(int),srcLen = kSize * sizeof(int), prosize = 5;
14    HANDLE hFile;
15    DWORD dwReaded = 8192;
16
17    memset(pInBuf, 0, kSize * sizeof(int));
18    memset(pOutBuf, 0, kSize * sizeof(int));
19    memset(pInBuf2, 0, kSize * sizeof(int));
20    memset(outprops, 05);
21
22    //for (i = 0; i < kSize; ++i)
23    //{
24    //    pInBuf[i] = i;
25    //    //if(S_OK != rand_s(&pInBuf[i]))
26    //    //{
27    //    //    printf("rand number failed.");
28    //    //    return E_FAIL;
29    //    //}
30    //}
31
32    hFile = CreateFile("C:\\i_ori.txt"// 文件大小不超过8000字节
33        GENERIC_READ | GENERIC_WRITE,
34        0,
35        0,
36        OPEN_ALWAYS,
37        FILE_ATTRIBUTE_NORMAL, 
38        NULL);
39    
40    ReadFile(hFile, pInBuf, 8192&dwReaded, 0);
41    CloseHandle(hFile);
42    
43    LzmaEncProps_Init(&props);
44    props.level = 5;
45    props.dictSize = 1 << 24;
46    props.lc = 3;
47    props.lp = 0;
48    props.pb = 2;
49    props.fb = 32;
50    props.numThreads = 2;
51    
52    srcLen = dwReaded;
53    destLen = (kSize) * sizeof(int);
54    res = LzmaEncode((Byte *)pOutBuf, &destLen, (Byte*)pInBuf, srcLen, &props, outprops, &prosize, 0,NULL, &g_Alloc, &g_Alloc);
55    if(0 != res)
56    {
57        printf("encoding error.");
58        return E_FAIL;
59    }

60
61    //srcLen = destLen;
62    //srcLen = kSize * sizeof(int); // 不要启用,否则下面的res可能返回6
63    //prosize = 5;
64    res = LzmaDecode((Byte *)pInBuf2, &srcLen, (Byte *)pOutBuf, &destLen, (const unsigned char*)outprops, (unsigned)prosize, LZMA_FINISH_ANY, &status, &g_Alloc);
65    if(S_OK != res)
66    {
67        printf("decode error.");
68        return E_FAIL;
69    }

70    nResult = memcmp(pInBuf, pInBuf2, srcLen);
71    return S_OK;
72}

经过测试,我发现存在频繁申请内存、申请内存的大小变化过大、运行后内存占用率过高。我没有及时找到解决办法,所以没有在项目中采用。

你可能感兴趣的:(LZMA 介绍)