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