|
LZMA,(Lempel-Ziv-Markov chain-Algorithm的縮寫),是一個Deflate和LZ77算法改良和優(yōu)化后的壓縮算法,開發(fā)者是Igor Pavlov,目前7zip等壓縮工具都使用了LZMA壓縮算法。
LZMA 的特性 - 可變的字典大小,可達(dá)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 - 解壓需要少量的內(nèi)存(16 KB + DictionarySize) - 解壓代碼量很少5-8 KB
在http://www.7-zip.org/sdk.html網(wǎng)頁上提供了LZMA的SDK開發(fā)包下載,包中的一級目錄中包含了如下內(nèi)容:ASM, C, Cpp, CS, Java文件夾,和7zc.txt、7zformat.txt、7zr.exe、history.txt、lzma.exe、lzma.txt、methods.txt文件。lzma.txt是重要的SDK文檔,其中介紹了LZMA的目錄結(jié)構(gòu)和一些方法的使用,這個文檔應(yīng)該首先看看。我著重看了C的版本,它位于C目錄下。在C/util目錄下有幾個目錄,這幾個目錄中的例子演示了如何使用lzma,lzma目錄中是源碼使用方式,LzmaLib中是DLL使用方式。其中的代碼很多是基于對文件的壓縮和解壓縮,我這里寫了一個內(nèi)存的壓縮示例,把這個方法放在lzma\LzmaUtil.c文件中調(diào)用就可以.
 code 1 int 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字節(jié) 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 }
經(jīng)過測試,我發(fā)現(xiàn)存在頻繁申請內(nèi)存、申請內(nèi)存的大小變化過大、運行后內(nèi)存占用率過高。我沒有及時找到解決辦法,所以沒有在項目中采用。
|