This free easy zlib C/C++ source code download makes it painless if you want simple in-memory XML compression (or any text, HTML, image or data compression) and decompression and don't want to spend time learning about zlib. |
Download Release 1.0 zip (85k) The zlib compression library is amalgamated in a single file easyzlib.c so you can easily add it to your C or C++ project without hassles. |
Download the zip file, open it, copy easyzlib.c and easyzlib.h and add them to your project. Use the ezcompress
and ezuncompress
functions to compress or decompress your source buffer to your destination buffer.
int ezcompress( unsigned char* pDest, long* pnDestLen, const unsigned char* pSrc, long nSrcLen ); int ezuncompress( unsigned char* pDest, long* pnDestLen, const unsigned char* pSrc, long nSrcLen );
These are the return codes:
Return code | Value | Likely reason |
---|---|---|
EZ_STREAM_ERROR | -2 | pDest is NULL |
EZ_DATA_ERROR | -3 | corrupted pSrc passed to ezuncompress |
EZ_MEM_ERROR | -4 | out of memory |
EZ_BUF_ERROR | -5 | pDest length is not enough |
The hard part of using compression functions is guessing or determining buffer sizes. With zlib, you are guaranteed the compressed result will be at most the size of the source plus 12 plus 0.1%. The easyzlib.h header defines EZ_COMPRESSMAXDESTLENGTH to do this calculation for you.
#define EZ_COMPRESSMAXDESTLENGTH(n) (n+(((n)/1000)+1)+12)
That is the maximum memory length of your compressed result. The actual compressed length will be returned from ezcompress
in pnDestLen
.
If you store the original size with your compressed result, you can allocate exactly the memory you need to decompress it later. However, if you don't know the decompressed size, or you don't want to allocate the maximum compress size, easy zlib provides another option...
In the core functions ezcompress
and ezuncompress
, I've added a feature that the regular zlib compress
and uncompress
functions don't have. If the destination buffer is too small, the functions still continue on to discover the required memory to complete the operation (which is returned in the pnDestLen
parameter).
This way you can pass a small buffer in order to find out the exact size and then allocate only the size you need, whether compressing or decompressing. Here is an example that allocates 8192
bytes up front and then allocates the actual size if 8192
wasn't enough.
long nDestLen = 8192; unsigned char* pDest = new unsigned char[nDestLen]; int nErr = ezuncompress( pDest, &nDestLen, pSrcBuf, nSrcLen ); if ( nErr == EZ_BUF_ERROR ) { delete[] pDest; pDest = new unsigned char[nDestLen]; // enough room now nErr = ezuncompress( pDest, &nDestLen, pSrcBuf, nSrcLen ); }
If you are using C++, there are additional overloaded functions implemented in easyzlib.h to make compression even easier. First of all there is a simple buffer class called ezbuffer
to streamline your code. By encapsulating the buffer pointer and length in a structure, your code is simpler, plus these functions automatically allocate the destination buffer to accomodate the result.
int ezcompress( ezbuffer& bufDest, const ezbuffer& bufSrc ); int ezuncompress( ezbuffer& bufDest, const ezbuffer& bufSrc );
The resulting destination length is returned in bufDest.nLen
. Here are the public members of ezbuffer
:
struct ezbuffer { ezbuffer(); // constructor ezbuffer( int n ); // constructor allocates n bytes ~ezbuffer(); // destructor unsigned char* Alloc( int n ); void Release(); unsigned char* pBuf; long nLen; // data length };
Here is an example reading nBytes
from a file into an ezbuffer
and compressing it into another ezbuffer
that is allocated automatically.
ezbuffer bufSrc( nBytes ); fread( bufSrc.pBuf, nBytes, 1, fp ); ezbuffer bufDest; ezcompress( bufDest, bufSrc );
C++ string functions are provided if you are using CMarkup and you include easylib.h after Markup.h since the necessary string types and functions are defined in Markup.h. Again, you do not need to estimate the size or do buffer allocations.
int ezcompress( ezbuffer& bufDest, const MCD_STR& strSrc ); int ezuncompress( MCD_STR& strDest, const ezbuffer& bufSrc );
To compress a string such as an XML document, just do the following:
ezbuffer buf; ezcompress( buf, xml.GetDoc() );
The buf
object now contains the compressed document. Use buf.pBuf
and buf.nLen
to access the compression data.
The zlib compression library is widely used compression software written by Jean-loup Gailly and Mark Adler which is free at zlib.net. If you download it there you will find 28 source code files (plus another 167 supporting files in 34 subfolders).
I've used zlib in numerous projects, and every time I've had to go through the hassle of adding 28 source files to my project. Plus I need to sort out exactly which functions I need, deflate
or compress
, inflate
or uncompress
, and which arguments, headers and settings. And there is jargon I have to familiarize myself with everytime I look through zlib.
Also, all of the headers create opportunities for compiling and naming conflicts. There is no reason for every piece of code that needs to compress and uncompress to compile gobs of zlib headers. Headers should provide only the prototypes you need.
multiply defined symbol errors in easy zlib
Dusan Stevanovic 08-Sep-2009
First of all thank you for developing and sharing this extremely useful lib. It has all I ever wanted from zlib, but in much smaller and easier to use package. :) I wanted you to know that I compiled it under mac OS X using xcode 3.1 (intel mac). I found only one issue, the linker was reporting duplicate symbols for function (since multiple source files have easy zlib included).
int ezcompress( ezbuffer& bufDest, const ezbuffer& bufSrc ) and similar...
I solved it by declaring the functions inline:
inline int ezcompress( ezbuffer& bufDest, const ezbuffer& bufSrc ) inline int ezuncompress( ezbuffer& bufDest, const ezbuffer& bufSrc ) inline int ezcompress( ezbuffer& bufDest, const MCD_STR& strSrc ) inline int ezuncompress( MCD_STR& strDest, const ezbuffer& bufSrc )
Thank you so much. Release 1.1 will incorporate this fix. In the meantime, all C++ users including easyzlib.h in multiple places will need to add the inline
keyword as described.
easy zlib written permission
Lars Olsson 13-Nov-2008
I want written permission to use easy zlib in our streaming server application. I needed a simple way to compress/decompress the payload of a certain message sent by UDP and it would be an incredible relief to just have to use your two files instead of the whole zlib.
You only need written permission if you want to redistribute easyzlib.c on the web or as part of a source code distribution. You can freely compile it in your commercial product, use it and modify it however you like. Best wishes with your project.
easy zlib checksum question
Mortaza Doulaty 01-Jun-2009
I've downloaded and used your easy zlib, it is really easy to use! But when I compress and decompress files using your library, the checksum of files are different. Here is my sample source code:
The reason the checksum was different on the saved file from the original was that the fopen
read mode was "r"
while the write mode was "wb"
. The read mode needed to be binary too, i.e. "rb"
. I'm putting the corrected code below as example C code to read a binary file, compress and decompress it, and write it back out.
FILE *f = fopen("C:\\sunset.bmp","rb"); fseek(f,0,SEEK_END); long bufferSize=ftell(f); fseek(f,0,SEEK_SET); unsigned char *buffer = new unsigned char[bufferSize]; ezbuffer b1(bufferSize),b2,b3; fread(b1.pBuf,bufferSize,1,f); fclose(f); ezcompress(b2,b1); ezuncompress(b3,b2); FILE *f2 = fopen("C:\\mrt.bmp","wb"); fwrite(b3.pBuf,1,b3.nLen,f2); fclose(f2);
Just wanted to say a big thank you for making the EasyZLib available. It lives up to it's name and saved much time and energy. I was just thinking why do we keep reinventing the wheel when your site suddenly leapt out of the Google page. In case you're wondering, I'm using it for blob compression in a Firebird database.