- 下载zlib
http://www.zlib.net/
- 编译zlib库
打开sln: zlib-1.2.11\contrib\vstudio\vc12\zlibvc.sln
生成库位置:
zlib-1.2.11\contrib\vstudio\vc12\x86\ZlibDllRelease
- 调用zlib库
添加lib依赖库位置:zlibwapi.lib的文件位置
添加zlibwapi.lib 在附加依赖库中 键入zlibwapi.lib
添加include位置:
需要两个头文件:
zconf.h
zlib.h
将其copy到一个文件夹中,然后附加到目录即可 - 一个例子
一个例子:
char text[] = "zlib compress and uncompress test\nturingo@163.com\n2012-11-05\n";char de_text[1024];uLong tlen = strlen(text) + 1; /* 需要把字符串的结束符'\0'也一并处理 */char* buf = NULL;uLong blen;/* 计算缓冲区大小,并为其分配内存 */blen = compressBound(tlen); /* 压缩后的长度是不会超过blen的 */if ((buf = (char*)malloc(sizeof(char) * blen)) == NULL){printf("no enough memory!\n");return -1;}/* 压缩 */if (compress((Bytef *)buf, &blen, (Bytef *)text, tlen) != Z_OK){printf("compress failed!\n");return -1;}/* 解压缩 */if (uncompress((Bytef *)de_text, &tlen, (Bytef *)buf, blen) != Z_OK){printf("uncompress failed!\n");return -1;}/* 打印结果,并释放内存 */printf("%s", de_text);if (buf != NULL){free(buf);buf = NULL;}return 0;
编译
一般会出现下面的错误
加入宏定义 :ZLIB_WINAPI
注意:
compress 与uncompress这两个简单接口中的类型转换
编码长度和解码长度尽可能保证在256以下,不然容易出错
官网上的测试代码有些许问题,将其更为256
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>#include "zlib.h"void MyDoMinus64(LARGE_INTEGER *R,LARGE_INTEGER A,LARGE_INTEGER B)
{R->HighPart = A.HighPart - B.HighPart;if (A.LowPart >= B.LowPart)R->LowPart = A.LowPart - B.LowPart;else{R->LowPart = A.LowPart - B.LowPart;R->HighPart --;}
}#ifdef _M_X64
// see http://msdn2.microsoft.com/library/twchhe95(en-us,vs.80).aspx for __rdtsc
unsigned __int64 __rdtsc(void);
void BeginCountRdtsc(LARGE_INTEGER * pbeginTime64)
{// printf("rdtsc = %I64x\n",__rdtsc());pbeginTime64->QuadPart=__rdtsc();
}LARGE_INTEGER GetResRdtsc(LARGE_INTEGER beginTime64,BOOL fComputeTimeQueryPerf)
{LARGE_INTEGER LIres;unsigned _int64 res=__rdtsc()-((unsigned _int64)(beginTime64.QuadPart));LIres.QuadPart=res;// printf("rdtsc = %I64x\n",__rdtsc());return LIres;
}
#else
#ifdef _M_IX86
void myGetRDTSC32(LARGE_INTEGER * pbeginTime64)
{DWORD dwEdx,dwEax;_asm{rdtscmov dwEax,eaxmov dwEdx,edx}pbeginTime64->LowPart=dwEax;pbeginTime64->HighPart=dwEdx;
}void BeginCountRdtsc(LARGE_INTEGER * pbeginTime64)
{myGetRDTSC32(pbeginTime64);
}LARGE_INTEGER GetResRdtsc(LARGE_INTEGER beginTime64,BOOL fComputeTimeQueryPerf)
{LARGE_INTEGER LIres,endTime64;myGetRDTSC32(&endTime64);LIres.LowPart=LIres.HighPart=0;MyDoMinus64(&LIres,endTime64,beginTime64);return LIres;
}
#else
void myGetRDTSC32(LARGE_INTEGER * pbeginTime64)
{
}void BeginCountRdtsc(LARGE_INTEGER * pbeginTime64)
{
}LARGE_INTEGER GetResRdtsc(LARGE_INTEGER beginTime64,BOOL fComputeTimeQueryPerf)
{LARGE_INTEGER lr;lr.QuadPart=0;return lr;
}
#endif
#endifvoid BeginCountPerfCounter(LARGE_INTEGER * pbeginTime64,BOOL fComputeTimeQueryPerf)
{if ((!fComputeTimeQueryPerf) || (!QueryPerformanceCounter(pbeginTime64))){pbeginTime64->LowPart = GetTickCount();pbeginTime64->HighPart = 0;}
}DWORD GetMsecSincePerfCounter(LARGE_INTEGER beginTime64,BOOL fComputeTimeQueryPerf)
{LARGE_INTEGER endTime64,ticksPerSecond,ticks;DWORDLONG ticksShifted,tickSecShifted;DWORD dwLog=16+0;DWORD dwRet;if ((!fComputeTimeQueryPerf) || (!QueryPerformanceCounter(&endTime64)))dwRet = (GetTickCount() - beginTime64.LowPart)*1;else{MyDoMinus64(&ticks,endTime64,beginTime64);QueryPerformanceFrequency(&ticksPerSecond);{ticksShifted = Int64ShrlMod32(*(DWORDLONG*)&ticks,dwLog);tickSecShifted = Int64ShrlMod32(*(DWORDLONG*)&ticksPerSecond,dwLog);}dwRet = (DWORD)((((DWORD)ticksShifted)*1000)/(DWORD)(tickSecShifted));dwRet *=1;}return dwRet;
}int ReadFileMemory(const char* filename,long* plFileSize,unsigned char** pFilePtr)
{FILE* stream;unsigned char* ptr;int retVal=1;stream=fopen(filename, "rb");if (stream==NULL)return 0;fseek(stream,0,SEEK_END);*plFileSize=ftell(stream);fseek(stream,0,SEEK_SET);ptr=malloc((*plFileSize)+1);if (ptr==NULL)retVal=0;else{if (fread(ptr, 1, *plFileSize,stream) != (*plFileSize))retVal=0;}fclose(stream);*pFilePtr=ptr;return retVal;
}int main(int argc, char *argv[])
{int BlockSizeCompress=256;int BlockSizeUncompress = 256;//0x8000; 注意需为256int cprLevel=Z_DEFAULT_COMPRESSION ;long lFileSize;unsigned char* FilePtr;long lBufferSizeCpr;long lBufferSizeUncpr;long lCompressedSize=0;unsigned char* CprPtr;unsigned char* UncprPtr;long lSizeCpr,lSizeUncpr;DWORD dwGetTick,dwMsecQP;LARGE_INTEGER li_qp,li_rdtsc,dwResRdtsc;if (argc<=1){printf("run TestZlib <File> [BlockSizeCompress] [BlockSizeUncompress] [compres. level]\n");return 0;}if (ReadFileMemory(argv[1],&lFileSize,&FilePtr)==0){printf("error reading %s\n",argv[1]);return 1;}else printf("file %s read, %u bytes\n",argv[1],lFileSize);if (argc>=3)BlockSizeCompress=atol(argv[2]);if (argc>=4)BlockSizeUncompress=atol(argv[3]);if (argc>=5)cprLevel=(int)atol(argv[4]);lBufferSizeCpr = lFileSize + (lFileSize/0x10) + 0x200;lBufferSizeUncpr = lBufferSizeCpr;CprPtr=(unsigned char*)malloc(lBufferSizeCpr + BlockSizeCompress);BeginCountPerfCounter(&li_qp,TRUE);dwGetTick=GetTickCount();BeginCountRdtsc(&li_rdtsc);{z_stream zcpr;int ret=Z_OK;long lOrigToDo = lFileSize;long lOrigDone = 0;int step=0;memset(&zcpr,0,sizeof(z_stream));deflateInit(&zcpr,cprLevel);zcpr.next_in = FilePtr;zcpr.next_out = CprPtr;do{long all_read_before = zcpr.total_in;zcpr.avail_in = min(lOrigToDo,BlockSizeCompress);zcpr.avail_out = BlockSizeCompress;ret=deflate(&zcpr,(zcpr.avail_in==lOrigToDo) ? Z_FINISH : Z_SYNC_FLUSH);lOrigDone += (zcpr.total_in-all_read_before);lOrigToDo -= (zcpr.total_in-all_read_before);step++;} while (ret==Z_OK);lSizeCpr=zcpr.total_out;deflateEnd(&zcpr);dwGetTick=GetTickCount()-dwGetTick;dwMsecQP=GetMsecSincePerfCounter(li_qp,TRUE);dwResRdtsc=GetResRdtsc(li_rdtsc,TRUE);printf("total compress size = %u, in %u step\n",lSizeCpr,step);printf("time = %u msec = %f sec\n",dwGetTick,dwGetTick/(double)1000.);printf("defcpr time QP = %u msec = %f sec\n",dwMsecQP,dwMsecQP/(double)1000.);printf("defcpr result rdtsc = %I64x\n\n",dwResRdtsc.QuadPart);}CprPtr=(unsigned char*)realloc(CprPtr,lSizeCpr);UncprPtr=(unsigned char*)malloc(lBufferSizeUncpr + BlockSizeUncompress);BeginCountPerfCounter(&li_qp,TRUE);dwGetTick=GetTickCount();BeginCountRdtsc(&li_rdtsc);{z_stream zcpr;int ret=Z_OK;long lOrigToDo = lSizeCpr;long lOrigDone = 0;int step=0;memset(&zcpr,0,sizeof(z_stream));inflateInit(&zcpr);zcpr.next_in = CprPtr;zcpr.next_out = UncprPtr;do{long all_read_before = zcpr.total_in;zcpr.avail_in = min(lOrigToDo,BlockSizeUncompress);zcpr.avail_out = BlockSizeUncompress;ret=inflate(&zcpr,Z_SYNC_FLUSH);lOrigDone += (zcpr.total_in-all_read_before);lOrigToDo -= (zcpr.total_in-all_read_before);step++;} while (ret==Z_OK);lSizeUncpr=zcpr.total_out;inflateEnd(&zcpr);dwGetTick=GetTickCount()-dwGetTick;dwMsecQP=GetMsecSincePerfCounter(li_qp,TRUE);dwResRdtsc=GetResRdtsc(li_rdtsc,TRUE);printf("total uncompress size = %u, in %u step\n",lSizeUncpr,step);printf("time = %u msec = %f sec\n",dwGetTick,dwGetTick/(double)1000.);printf("uncpr time QP = %u msec = %f sec\n",dwMsecQP,dwMsecQP/(double)1000.);printf("uncpr result rdtsc = %I64x\n\n",dwResRdtsc.QuadPart);}if (lSizeUncpr==lFileSize){if (memcmp(FilePtr,UncprPtr,lFileSize)==0)printf("compare ok\n");}return 0;
}
这里,zlib只是把一段内存压缩,压缩后放的另一段内存上,这离压缩文件甚至文件夹的目标还很远
zlib介绍
zlib是提供数据压缩用的函式库,由Jean-loup Gailly与Mark Adler所开发,初版0.9版在1995年5月1日发表。zlib使用DEFLATE算法,最初是为libpng函式库所写的,后来普遍为许多软件所使用。此函式库为自由软件,使用zlib授权
参考资料
CSDN博客(http://blog.csdn.net/JasonDing1354/article/details/42676685)
http://blog.csdn.net/gubenpeiyuan/article/details/8734290