MY_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen,
unsigned char *outProps, size_t *outPropsSize,
int level,
unsigned dictSize,
int lc,
int lp,
int pb,
int fb,
int numThreads
);
MY_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, SizeT *srcLen,
const unsigned char *props, size_t propsSize);
導入Types.h 和 Lzmalib.h 到工程中。
代碼如下:
#include "stdafx.h"
#include "LzmaLib.h"
#pragma comment(lib,"lzma.lib")
int _tmain(int argc, _TCHAR* argv[])
{
FILE* pFile = _tfopen(_T("file.dat"), _T("rb"));
if (pFile == NULL)
{
_ftprintf(stderr, _T("Error to Open the file!"));
return - 1;
}
fseek(pFile, 0, SEEK_END);
size_t srcLen = ftell(pFile);
rewind(pFile);
size_t destLen = srcLen * 2;
unsigned char* psrcRead = new unsigned char[srcLen]; //原始文件數據
unsigned char* pDecomress = new unsigned char[srcLen]; //存放解壓縮數據
unsigned char* pLzma = new unsigned char[destLen]; //存放壓縮數據
fread(psrcRead, sizeof(char), srcLen, pFile);
unsigned char prop[5] =
{
0
};
size_t sizeProp = 5;
if (SZ_OK != LzmaCompress(pLzma, &destLen, psrcRead, srcLen, prop,
&sizeProp, 9, (1 << 24), 3, 0, 2, 32, 2))
{
//出錯了
_ftprintf(stderr, _T("壓縮時出錯!"));
delete [] psrcRead;
delete [] pDecomress;
delete [] pLzma;
fclose(pFile);
return - 1;
}
FILE* pCompressFile = _tfopen(_T("compress.dat"), _T("wb"));
//寫入壓縮後的數據
if (pCompressFile == NULL)
{
_ftprintf(stderr, _T("創建文件出錯!"));
delete [] psrcRead;
delete [] pDecomress;
delete [] pLzma;
fclose(pFile);
return - 1;
}
fwrite(pLzma, sizeof(char), destLen, pCompressFile);
fclose(pCompressFile);
FILE* pDecompressFile = _tfopen(_T("decompress.dat"), _T("wb"));
//寫入解壓縮數據
if (pDecompressFile == NULL)
{
_ftprintf(stderr, _T("寫入數據出錯!"));
delete [] psrcRead;
delete [] pDecomress;
delete [] pLzma;
fclose(pFile);
return - 1;
}
//注意:解壓縮時props參數要使用壓縮時生成的outProps,這樣才能正常解壓縮
if (SZ_OK != LzmaUncompress(pDecomress, &srcLen, pLzma, &destLen, prop, 5))
{
delete [] psrcRead;
delete [] pDecomress;
delete [] pLzma;
fclose(pDecompressFile);
fclose(pFile);
return - 1;
}
fwrite(pDecomress, sizeof(char), srcLen, pDecompressFile);
delete [] psrcRead;
delete [] pDecomress;
delete [] pLzma;
fclose(pDecompressFile);
fclose(pFile);
return 0;
}
zlib使用:
zlib 是通用的壓縮庫,提供了一套 in-memory 壓縮和解壓函數,並能檢測解壓出來的數據的完整性(integrity)。下面介紹兩個最有用的函數——compress 和 uncompress。
int compress(Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen);
compress函數將 source 緩衝區中的內容壓縮到 dest 緩衝區。 sourceLen 表示source 緩衝區的大小(以字節計)。注意函數的第二個參數 destLen 是傳址調用。當調用函數時,destLen表示 dest 緩衝區的大小,destLen > (sourceLen + 12)*100.1%。當函數退出後,destLen 表示壓縮後緩衝區的實際大小。此時 destLen / sourceLen 正好是壓縮率。
compress 若成功,則返回 Z_OK;若沒有足夠內存,則返回 Z_MEM_ERROR;若輸出緩衝區不夠大,則返回 Z_BUF_ERROR。
int uncompress(Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen);
uncompress 函數將 source 緩衝區的內容解壓縮到 dest 緩衝區。sourceLen 是 source 緩衝區的大小(以字節計)。注意函數的第二個參數 destLen 是傳址調用。當調用函數時,destLen 表示 dest 緩衝區的大小, dest 緩衝區要足以容下解壓後的數據。在進行解壓縮時,需要提前知道被壓縮的數據解壓出來會有多大。這就要求在進行壓縮之前,保存原始數據的大小(也就是解壓後的數據的大小)。這不是 zlib 函數庫的功能,需要我們做額外的工作。當函數退出後, destLen 是解壓出來的數據的實際大小。
uncompress 若成功,則返回 Z_OK ;若沒有足夠內存,則返回 Z_MEM_ERROR;若輸出緩衝區不夠大,則返回 Z_BUF_ERROR。若輸入數據有誤,則返回 Z_DATA_ERROR。
代碼如下:
#include "stdafx.h"
#include <cstring>
#include <cstdlib>
#include <iostream>
#include "zlib.h"
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
int err = 0;
Byte compr[200] = {0}, uncompr[200] = {0}; // big enough
uLong comprLen = 0, uncomprLen = 0;
const char* hello = "12345678901234567890123456789012345678901234567890";
uLong len = strlen(hello) + 1;
comprLen = sizeof(compr) / sizeof(compr[0]);
err = compress(compr, &comprLen, (const Bytef*)hello, len);
if (err != Z_OK)
{
cerr << "compess error: " << err << '\n';
exit(1);
}
cout << "orignal size: " << len
<< " , compressed size : " << comprLen << '\n';
strcpy((char*)uncompr, "garbage");
err = uncompress(uncompr, &uncomprLen, compr, comprLen);
if (err != Z_OK)
{
cerr << "uncompess error: " << err << '\n';
exit(1);
}
cout << "orignal size: " << len
<< " , uncompressed size : " << uncomprLen << '\n';
if (strcmp((char*)uncompr, hello))
{
cerr << "BAD uncompress!!!\n";
exit(1);
}
else
{
cout << "uncompress() succeed: \n" << (char*)uncompr;
}
}