kusano 7d535a
Puff -- A Simple Inflate
kusano 7d535a
3 Mar 2003
kusano 7d535a
Mark Adler
kusano 7d535a
madler@alumni.caltech.edu
kusano 7d535a
kusano 7d535a
What this is --
kusano 7d535a
kusano 7d535a
puff.c provides the routine puff() to decompress the deflate data format.  It
kusano 7d535a
does so more slowly than zlib, but the code is about one-fifth the size of the
kusano 7d535a
inflate code in zlib, and written to be very easy to read.
kusano 7d535a
kusano 7d535a
Why I wrote this --
kusano 7d535a
kusano 7d535a
puff.c was written to document the deflate format unambiguously, by virtue of
kusano 7d535a
being working C code.  It is meant to supplement RFC 1951, which formally
kusano 7d535a
describes the deflate format.  I have received many questions on details of the
kusano 7d535a
deflate format, and I hope that reading this code will answer those questions.
kusano 7d535a
puff.c is heavily commented with details of the deflate format, especially
kusano 7d535a
those little nooks and cranies of the format that might not be obvious from a
kusano 7d535a
specification.
kusano 7d535a
kusano 7d535a
puff.c may also be useful in applications where code size or memory usage is a
kusano 7d535a
very limited resource, and speed is not as important.
kusano 7d535a
kusano 7d535a
How to use it --
kusano 7d535a
kusano 7d535a
Well, most likely you should just be reading puff.c and using zlib for actual
kusano 7d535a
applications, but if you must ...
kusano 7d535a
kusano 7d535a
Include puff.h in your code, which provides this prototype:
kusano 7d535a
kusano 7d535a
int puff(unsigned char *dest,           /* pointer to destination pointer */
kusano 7d535a
         unsigned long *destlen,        /* amount of output space */
kusano 7d535a
         unsigned char *source,         /* pointer to source data pointer */
kusano 7d535a
         unsigned long *sourcelen);     /* amount of input available */
kusano 7d535a
kusano 7d535a
Then you can call puff() to decompress a deflate stream that is in memory in
kusano 7d535a
its entirety at source, to a sufficiently sized block of memory for the
kusano 7d535a
decompressed data at dest.  puff() is the only external symbol in puff.c  The
kusano 7d535a
only C library functions that puff.c needs are setjmp() and longjmp(), which
kusano 7d535a
are used to simplify error checking in the code to improve readabilty.  puff.c
kusano 7d535a
does no memory allocation, and uses less than 2K bytes off of the stack.
kusano 7d535a
kusano 7d535a
If destlen is not enough space for the uncompressed data, then inflate will
kusano 7d535a
return an error without writing more than destlen bytes.  Note that this means
kusano 7d535a
that in order to decompress the deflate data successfully, you need to know
kusano 7d535a
the size of the uncompressed data ahead of time.
kusano 7d535a
kusano 7d535a
If needed, puff() can determine the size of the uncompressed data with no
kusano 7d535a
output space.  This is done by passing dest equal to (unsigned char *)0.  Then
kusano 7d535a
the initial value of *destlen is ignored and *destlen is set to the length of
kusano 7d535a
the uncompressed data.  So if the size of the uncompressed data is not known,
kusano 7d535a
then two passes of puff() can be used--first to determine the size, and second
kusano 7d535a
to do the actual inflation after allocating the appropriate memory.  Not
kusano 7d535a
pretty, but it works.  (This is one of the reasons you should be using zlib.)
kusano 7d535a
kusano 7d535a
The deflate format is self-terminating.  If the deflate stream does not end
kusano 7d535a
in *sourcelen bytes, puff() will return an error without reading at or past
kusano 7d535a
endsource.
kusano 7d535a
kusano 7d535a
On return, *sourcelen is updated to the amount of input data consumed, and
kusano 7d535a
*destlen is updated to the size of the uncompressed data.  See the comments
kusano 7d535a
in puff.c for the possible return codes for puff().