|
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, 0, 5); 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}
经过测试,我发现存在频繁申请内存、申请内存的大小变化过大、运行后内存占用率过高。我没有及时找到解决办法,所以没有在项目中采用。
|