1 /*
2  * Header file for my independent implementation of Deflate
3  * (RFC1951) compression.
4  */
5 
6 #ifndef DEFLATE_DEFLATE_H
7 #define DEFLATE_DEFLATE_H
8 
9 /*
10  * Types of Deflate data stream.
11  *
12  * DEFLATE_TYPE_BARE represents the basic Deflate data format, as
13  * defined in RFC 1951. It has no checksum to detect errors and no
14  * magic-number header for ease of recognition, but it does have
15  * internal EOF indication.
16  *
17  * DEFLATE_TYPE_ZLIB represents the zlib container format, as
18  * defined in RFC 1950. It has a two-byte header, and a four-byte
19  * Adler32 checksum at the end to verify correct decoding, but
20  * apart from those six bytes it's exactly equivalent to
21  * DEFLATE_TYPE_BARE.
22  *
23  * DEFLATE_TYPE_GZIP represents the gzip compressed file format, as
24  * defined in RFC 1952. This is a more full-featured format, with a
25  * magic number, a CRC checksum of the compressed data, and various
26  * header features including storing the original filename. This
27  * implementation accepts but ignores all of those features on
28  * input except the checksum, and outputs them in the most trivial
29  * fashion. Also, this implementation will not decode multiple
30  * concatenated gzip members (permitted by the RFC).
31  */
32 enum {
33     DEFLATE_TYPE_BARE,
34     DEFLATE_TYPE_ZLIB,
35     DEFLATE_TYPE_GZIP
36 };
37 
38 /* ----------------------------------------------------------------------
39  * Compression functions. Create a compression context with
40  * deflate_compress_new(); feed it data with repeated calls to
41  * deflate_compress_data(); destroy it with
42  * deflate_compress_free().
43  */
44 
45 typedef struct deflate_compress_ctx deflate_compress_ctx;
46 
47 /*
48  * Create a new compression context. `type' indicates whether it's
49  * bare Deflate (as used in, say, zip files) or Zlib (as used in,
50  * say, PDF).
51  */
52 deflate_compress_ctx *deflate_compress_new(int type);
53 
54 /*
55  * Free a compression context previously allocated by
56  * deflate_compress_new().
57  */
58 void deflate_compress_free(deflate_compress_ctx *ctx);
59 
60 /*
61  * Give the compression context some data to compress. The input
62  * data is passed in `inblock', and has length `inlen'. This
63  * function may or may not produce some output data; if so, it is
64  * written to a dynamically allocated chunk of memory, a pointer to
65  * that memory is stored in `outblock', and the length of output
66  * data is stored in `outlen'. It is common for no data to be
67  * output, if the input data has merely been stored in internal
68  * buffers.
69  *
70  * `flushtype' indicates whether you want to force buffered data to
71  * be output. It can be one of the following values:
72  *
73  *  - DEFLATE_NO_FLUSH: nothing is output if the compressor would
74  *    rather not. Use this when the best compression is desired
75  *    (i.e. most of the time).
76  *
77  *  - DEFLATE_SYNC_FLUSH: all the buffered data is output, but the
78  *    compressed data stream remains open and ready to continue
79  *    compressing data. Use this in interactive protocols when a
80  *    single compressed data stream is split across several network
81  *    packets.
82  *
83  *  - DEFLATE_END_OF_DATA: all the buffered data is output and the
84  *    compressed data stream is cleaned up. Any checksums required
85  *    at the end of the stream are also output.
86  */
87 void deflate_compress_data(deflate_compress_ctx *ctx,
88 			   const void *inblock, int inlen, int flushtype,
89 			   void **outblock, int *outlen);
90 
91 enum {
92     DEFLATE_NO_FLUSH,
93     DEFLATE_SYNC_FLUSH,
94     DEFLATE_END_OF_DATA
95 };
96 
97 /* ----------------------------------------------------------------------
98  * Decompression functions. Create a decompression context with
99  * deflate_decompress_new(); feed it data with repeated calls to
100  * deflate_decompress_data(); destroy it with
101  * deflate_decompress_free().
102  */
103 
104 typedef struct deflate_decompress_ctx deflate_decompress_ctx;
105 
106 /*
107  * Create a new decompression context. `type' means the same as it
108  * does in deflate_compress_new().
109  */
110 deflate_decompress_ctx *deflate_decompress_new(int type);
111 
112 /*
113  * Free a decompression context previously allocated by
114  * deflate_decompress_new().
115  */
116 void deflate_decompress_free(deflate_decompress_ctx *ctx);
117 
118 /*
119  * Give the decompression context some data to decompress. The
120  * input data is passed in `inblock', and has length `inlen'. This
121  * function may or may not produce some output data; if so, it is
122  * written to a dynamically allocated chunk of memory, a pointer to
123  * that memory is stored in `outblock', and the length of output
124  * data is stored in `outlen'.
125  *
126  * Returns 0 on success, or a non-zero error code if there was a
127  * decoding error. In case of an error return, the data decoded
128  * before the error is still returned as well. The possible errors
129  * are listed below.
130  *
131  * If you want to check that the compressed data stream was
132  * correctly terminated, you can call this function with inlen==0
133  * to signal input EOF and see if an error comes back. If you don't
134  * care, don't bother.
135  */
136 int deflate_decompress_data(deflate_decompress_ctx *ctx,
137 			    const void *inblock, int inlen,
138 			    void **outblock, int *outlen);
139 
140 /*
141  * Enumeration of error codes. The strange macro is so that I can
142  * define description arrays in the accompanying source.
143  */
144 #define DEFLATE_ERRORLIST(A) \
145     A(DEFLATE_NO_ERR, "success"), \
146     A(DEFLATE_ERR_ZLIB_HEADER, "invalid zlib header"), \
147     A(DEFLATE_ERR_ZLIB_WRONGCOMP, "zlib header specifies non-deflate compression"), \
148     A(DEFLATE_ERR_GZIP_HEADER, "invalid gzip header"), \
149     A(DEFLATE_ERR_GZIP_WRONGCOMP, "gzip header specifies non-deflate compression"), \
150     A(DEFLATE_ERR_GZIP_FHCRC, "gzip header specifies disputed FHCRC flag"), \
151     A(DEFLATE_ERR_SMALL_HUFTABLE, "under-committed Huffman code space"), \
152     A(DEFLATE_ERR_LARGE_HUFTABLE, "over-committed Huffman code space"), \
153     A(DEFLATE_ERR_UNCOMP_HDR, "wrongly formatted header in uncompressed block"), \
154     A(DEFLATE_ERR_NODISTTABLE, "backward copy encoded in block without distances table"), \
155     A(DEFLATE_ERR_BADDISTCODE, "invalid distance code 30 or 31 found in block"), \
156     A(DEFLATE_ERR_CHECKSUM, "incorrect data checksum"), \
157     A(DEFLATE_ERR_INLEN, "incorrect data length"), \
158     A(DEFLATE_ERR_UNEXPECTED_EOF, "unexpected end of data")
159 #define DEFLATE_ENUM_DEF(x,y) x
160 enum { DEFLATE_ERRORLIST(DEFLATE_ENUM_DEF), DEFLATE_NUM_ERRORS };
161 #undef DEFLATE_ENUM_DEF
162 
163 /*
164  * Arrays mapping the above error codes to, respectively, a text
165  * error string and a textual representation of the symbolic error
166  * code.
167  */
168 extern const char *const deflate_error_msg[DEFLATE_NUM_ERRORS];
169 extern const char *const deflate_error_sym[DEFLATE_NUM_ERRORS];
170 
171 #endif /* DEFLATE_DEFLATE_H */
172