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