1b33c96954667ba382fa595baf7b31290bfdd517vboxsyncPuff -- A Simple Inflate
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync3 Mar 2003
1b33c96954667ba382fa595baf7b31290bfdd517vboxsyncMark Adler
1b33c96954667ba382fa595baf7b31290bfdd517vboxsyncmadler@alumni.caltech.edu
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsyncWhat this is --
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsyncpuff.c provides the routine puff() to decompress the deflate data format. It
1b33c96954667ba382fa595baf7b31290bfdd517vboxsyncdoes so more slowly than zlib, but the code is about one-fifth the size of the
1b33c96954667ba382fa595baf7b31290bfdd517vboxsyncinflate code in zlib, and written to be very easy to read.
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsyncWhy I wrote this --
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsyncpuff.c was written to document the deflate format unambiguously, by virtue of
1b33c96954667ba382fa595baf7b31290bfdd517vboxsyncbeing working C code. It is meant to supplement RFC 1951, which formally
1b33c96954667ba382fa595baf7b31290bfdd517vboxsyncdescribes the deflate format. I have received many questions on details of the
1b33c96954667ba382fa595baf7b31290bfdd517vboxsyncdeflate format, and I hope that reading this code will answer those questions.
1b33c96954667ba382fa595baf7b31290bfdd517vboxsyncpuff.c is heavily commented with details of the deflate format, especially
1b33c96954667ba382fa595baf7b31290bfdd517vboxsyncthose little nooks and cranies of the format that might not be obvious from a
1b33c96954667ba382fa595baf7b31290bfdd517vboxsyncspecification.
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsyncpuff.c may also be useful in applications where code size or memory usage is a
1b33c96954667ba382fa595baf7b31290bfdd517vboxsyncvery limited resource, and speed is not as important.
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsyncHow to use it --
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsyncWell, most likely you should just be reading puff.c and using zlib for actual
1b33c96954667ba382fa595baf7b31290bfdd517vboxsyncapplications, but if you must ...
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsyncInclude puff.h in your code, which provides this prototype:
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsyncint puff(unsigned char *dest, /* pointer to destination pointer */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync unsigned long *destlen, /* amount of output space */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync unsigned char *source, /* pointer to source data pointer */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync unsigned long *sourcelen); /* amount of input available */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsyncThen you can call puff() to decompress a deflate stream that is in memory in
1b33c96954667ba382fa595baf7b31290bfdd517vboxsyncits entirety at source, to a sufficiently sized block of memory for the
1b33c96954667ba382fa595baf7b31290bfdd517vboxsyncdecompressed data at dest. puff() is the only external symbol in puff.c The
1b33c96954667ba382fa595baf7b31290bfdd517vboxsynconly C library functions that puff.c needs are setjmp() and longjmp(), which
1b33c96954667ba382fa595baf7b31290bfdd517vboxsyncare used to simplify error checking in the code to improve readabilty. puff.c
1b33c96954667ba382fa595baf7b31290bfdd517vboxsyncdoes no memory allocation, and uses less than 2K bytes off of the stack.
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsyncIf destlen is not enough space for the uncompressed data, then inflate will
1b33c96954667ba382fa595baf7b31290bfdd517vboxsyncreturn an error without writing more than destlen bytes. Note that this means
1b33c96954667ba382fa595baf7b31290bfdd517vboxsyncthat in order to decompress the deflate data successfully, you need to know
1b33c96954667ba382fa595baf7b31290bfdd517vboxsyncthe size of the uncompressed data ahead of time.
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsyncIf needed, puff() can determine the size of the uncompressed data with no
1b33c96954667ba382fa595baf7b31290bfdd517vboxsyncoutput space. This is done by passing dest equal to (unsigned char *)0. Then
1b33c96954667ba382fa595baf7b31290bfdd517vboxsyncthe initial value of *destlen is ignored and *destlen is set to the length of
1b33c96954667ba382fa595baf7b31290bfdd517vboxsyncthe uncompressed data. So if the size of the uncompressed data is not known,
1b33c96954667ba382fa595baf7b31290bfdd517vboxsyncthen two passes of puff() can be used--first to determine the size, and second
1b33c96954667ba382fa595baf7b31290bfdd517vboxsyncto do the actual inflation after allocating the appropriate memory. Not
1b33c96954667ba382fa595baf7b31290bfdd517vboxsyncpretty, but it works. (This is one of the reasons you should be using zlib.)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsyncThe deflate format is self-terminating. If the deflate stream does not end
1b33c96954667ba382fa595baf7b31290bfdd517vboxsyncin *sourcelen bytes, puff() will return an error without reading at or past
1b33c96954667ba382fa595baf7b31290bfdd517vboxsyncendsource.
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsyncOn return, *sourcelen is updated to the amount of input data consumed, and
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync*destlen is updated to the size of the uncompressed data. See the comments
1b33c96954667ba382fa595baf7b31290bfdd517vboxsyncin puff.c for the possible return codes for puff().