| 1 | 
 Puff -- A Simple Inflate | 
 
 
 
 
 
 | 2 | 
 3 Mar 2003 | 
 
 
 
 
 
 | 3 | 
 Mark Adler | 
 
 
 
 
 
 | 4 | 
 madler@alumni.caltech.edu | 
 
 
 
 
 
 | 5 | 
  | 
 
 
 
 
 
 | 6 | 
 What this is -- | 
 
 
 
 
 
 | 7 | 
  | 
 
 
 
 
 
 | 8 | 
 puff.c provides the routine puff() to decompress the deflate data format.  It | 
 
 
 
 
 
 | 9 | 
 does so more slowly than zlib, but the code is about one-fifth the size of the | 
 
 
 
 
 
 | 10 | 
 inflate code in zlib, and written to be very easy to read. | 
 
 
 
 
 
 | 11 | 
  | 
 
 
 
 
 
 | 12 | 
 Why I wrote this -- | 
 
 
 
 
 
 | 13 | 
  | 
 
 
 
 
 
 | 14 | 
 puff.c was written to document the deflate format unambiguously, by virtue of | 
 
 
 
 
 
 | 15 | 
 being working C code.  It is meant to supplement RFC 1951, which formally | 
 
 
 
 
 
 | 16 | 
 describes the deflate format.  I have received many questions on details of the | 
 
 
 
 
 
 | 17 | 
 deflate format, and I hope that reading this code will answer those questions. | 
 
 
 
 
 
 | 18 | 
 puff.c is heavily commented with details of the deflate format, especially | 
 
 
 
 
 
 | 19 | 
 those little nooks and cranies of the format that might not be obvious from a | 
 
 
 
 
 
 | 20 | 
 specification. | 
 
 
 
 
 
 | 21 | 
  | 
 
 
 
 
 
 | 22 | 
 puff.c may also be useful in applications where code size or memory usage is a | 
 
 
 
 
 
 | 23 | 
 very limited resource, and speed is not as important. | 
 
 
 
 
 
 | 24 | 
  | 
 
 
 
 
 
 | 25 | 
 How to use it -- | 
 
 
 
 
 
 | 26 | 
  | 
 
 
 
 
 
 | 27 | 
 Well, most likely you should just be reading puff.c and using zlib for actual | 
 
 
 
 
 
 | 28 | 
 applications, but if you must ... | 
 
 
 
 
 
 | 29 | 
  | 
 
 
 
 
 
 | 30 | 
 Include puff.h in your code, which provides this prototype: | 
 
 
 
 
 
 | 31 | 
  | 
 
 
 
 
 
 | 32 | 
 int puff(unsigned char *dest,           /* pointer to destination pointer */ | 
 
 
 
 
 
 | 33 | 
          unsigned long *destlen,        /* amount of output space */ | 
 
 
 
 
 
 | 34 | 
          unsigned char *source,         /* pointer to source data pointer */ | 
 
 
 
 
 
 | 35 | 
          unsigned long *sourcelen);     /* amount of input available */ | 
 
 
 
 
 
 | 36 | 
  | 
 
 
 
 
 
 | 37 | 
 Then you can call puff() to decompress a deflate stream that is in memory in | 
 
 
 
 
 
 | 38 | 
 its entirety at source, to a sufficiently sized block of memory for the | 
 
 
 
 
 
 | 39 | 
 decompressed data at dest.  puff() is the only external symbol in puff.c  The | 
 
 
 
 
 
 | 40 | 
 only C library functions that puff.c needs are setjmp() and longjmp(), which | 
 
 
 
 
 
 | 41 | 
 are used to simplify error checking in the code to improve readabilty.  puff.c | 
 
 
 
 
 
 | 42 | 
 does no memory allocation, and uses less than 2K bytes off of the stack. | 
 
 
 
 
 
 | 43 | 
  | 
 
 
 
 
 
 | 44 | 
 If destlen is not enough space for the uncompressed data, then inflate will | 
 
 
 
 
 
 | 45 | 
 return an error without writing more than destlen bytes.  Note that this means | 
 
 
 
 
 
 | 46 | 
 that in order to decompress the deflate data successfully, you need to know | 
 
 
 
 
 
 | 47 | 
 the size of the uncompressed data ahead of time. | 
 
 
 
 
 
 | 48 | 
  | 
 
 
 
 
 
 | 49 | 
 If needed, puff() can determine the size of the uncompressed data with no | 
 
 
 
 
 
 | 50 | 
 output space.  This is done by passing dest equal to (unsigned char *)0.  Then | 
 
 
 
 
 
 | 51 | 
 the initial value of *destlen is ignored and *destlen is set to the length of | 
 
 
 
 
 
 | 52 | 
 the uncompressed data.  So if the size of the uncompressed data is not known, | 
 
 
 
 
 
 | 53 | 
 then two passes of puff() can be used--first to determine the size, and second | 
 
 
 
 
 
 | 54 | 
 to do the actual inflation after allocating the appropriate memory.  Not | 
 
 
 
 
 
 | 55 | 
 pretty, but it works.  (This is one of the reasons you should be using zlib.) | 
 
 
 
 
 
 | 56 | 
  | 
 
 
 
 
 
 | 57 | 
 The deflate format is self-terminating.  If the deflate stream does not end | 
 
 
 
 
 
 | 58 | 
 in *sourcelen bytes, puff() will return an error without reading at or past | 
 
 
 
 
 
 | 59 | 
 endsource. | 
 
 
 
 
 
 | 60 | 
  | 
 
 
 
 
 
 | 61 | 
 On return, *sourcelen is updated to the amount of input data consumed, and | 
 
 
 
 
 
 | 62 | 
 *destlen is updated to the size of the uncompressed data.  See the comments | 
 
 
 
 
 
 | 63 | 
 in puff.c for the possible return codes for puff(). |