14e00368fSchristos /* blast.c
2*699b0f92Schristos * Copyright (C) 2003, 2012, 2013 Mark Adler
34e00368fSchristos * For conditions of distribution and use, see copyright notice in blast.h
4*699b0f92Schristos * version 1.3, 24 Aug 2013
54e00368fSchristos *
64e00368fSchristos * blast.c decompresses data compressed by the PKWare Compression Library.
74e00368fSchristos * This function provides functionality similar to the explode() function of
84e00368fSchristos * the PKWare library, hence the name "blast".
94e00368fSchristos *
104e00368fSchristos * This decompressor is based on the excellent format description provided by
114e00368fSchristos * Ben Rudiak-Gould in comp.compression on August 13, 2001. Interestingly, the
124e00368fSchristos * example Ben provided in the post is incorrect. The distance 110001 should
134e00368fSchristos * instead be 111000. When corrected, the example byte stream becomes:
144e00368fSchristos *
154e00368fSchristos * 00 04 82 24 25 8f 80 7f
164e00368fSchristos *
174e00368fSchristos * which decompresses to "AIAIAIAIAIAIA" (without the quotes).
184e00368fSchristos */
194e00368fSchristos
204e00368fSchristos /*
214e00368fSchristos * Change history:
224e00368fSchristos *
234e00368fSchristos * 1.0 12 Feb 2003 - First version
244e00368fSchristos * 1.1 16 Feb 2003 - Fixed distance check for > 4 GB uncompressed data
25ed8eb4c2Schristos * 1.2 24 Oct 2012 - Add note about using binary mode in stdio
26ed8eb4c2Schristos * - Fix comparisons of differently signed integers
27*699b0f92Schristos * 1.3 24 Aug 2013 - Return unused input from blast()
28*699b0f92Schristos * - Fix test code to correctly report unused input
29*699b0f92Schristos * - Enable the provision of initial input to blast()
304e00368fSchristos */
314e00368fSchristos
32*699b0f92Schristos #include <stddef.h> /* for NULL */
334e00368fSchristos #include <setjmp.h> /* for setjmp(), longjmp(), and jmp_buf */
344e00368fSchristos #include "blast.h" /* prototype for blast() */
354e00368fSchristos
364e00368fSchristos #define local static /* for local function definitions */
374e00368fSchristos #define MAXBITS 13 /* maximum code length */
384e00368fSchristos #define MAXWIN 4096 /* maximum window size */
394e00368fSchristos
404e00368fSchristos /* input and output state */
414e00368fSchristos struct state {
424e00368fSchristos /* input state */
434e00368fSchristos blast_in infun; /* input function provided by user */
444e00368fSchristos void *inhow; /* opaque information passed to infun() */
454e00368fSchristos unsigned char *in; /* next input location */
464e00368fSchristos unsigned left; /* available input at in */
474e00368fSchristos int bitbuf; /* bit buffer */
484e00368fSchristos int bitcnt; /* number of bits in bit buffer */
494e00368fSchristos
504e00368fSchristos /* input limit error return state for bits() and decode() */
514e00368fSchristos jmp_buf env;
524e00368fSchristos
534e00368fSchristos /* output state */
544e00368fSchristos blast_out outfun; /* output function provided by user */
554e00368fSchristos void *outhow; /* opaque information passed to outfun() */
564e00368fSchristos unsigned next; /* index of next write location in out[] */
574e00368fSchristos int first; /* true to check distances (for first 4K) */
584e00368fSchristos unsigned char out[MAXWIN]; /* output buffer and sliding window */
594e00368fSchristos };
604e00368fSchristos
614e00368fSchristos /*
624e00368fSchristos * Return need bits from the input stream. This always leaves less than
634e00368fSchristos * eight bits in the buffer. bits() works properly for need == 0.
644e00368fSchristos *
654e00368fSchristos * Format notes:
664e00368fSchristos *
674e00368fSchristos * - Bits are stored in bytes from the least significant bit to the most
684e00368fSchristos * significant bit. Therefore bits are dropped from the bottom of the bit
694e00368fSchristos * buffer, using shift right, and new bytes are appended to the top of the
704e00368fSchristos * bit buffer, using shift left.
714e00368fSchristos */
bits(struct state * s,int need)724e00368fSchristos local int bits(struct state *s, int need)
734e00368fSchristos {
744e00368fSchristos int val; /* bit accumulator */
754e00368fSchristos
764e00368fSchristos /* load at least need bits into val */
774e00368fSchristos val = s->bitbuf;
784e00368fSchristos while (s->bitcnt < need) {
794e00368fSchristos if (s->left == 0) {
804e00368fSchristos s->left = s->infun(s->inhow, &(s->in));
814e00368fSchristos if (s->left == 0) longjmp(s->env, 1); /* out of input */
824e00368fSchristos }
834e00368fSchristos val |= (int)(*(s->in)++) << s->bitcnt; /* load eight bits */
844e00368fSchristos s->left--;
854e00368fSchristos s->bitcnt += 8;
864e00368fSchristos }
874e00368fSchristos
884e00368fSchristos /* drop need bits and update buffer, always zero to seven bits left */
894e00368fSchristos s->bitbuf = val >> need;
904e00368fSchristos s->bitcnt -= need;
914e00368fSchristos
924e00368fSchristos /* return need bits, zeroing the bits above that */
934e00368fSchristos return val & ((1 << need) - 1);
944e00368fSchristos }
954e00368fSchristos
964e00368fSchristos /*
974e00368fSchristos * Huffman code decoding tables. count[1..MAXBITS] is the number of symbols of
984e00368fSchristos * each length, which for a canonical code are stepped through in order.
994e00368fSchristos * symbol[] are the symbol values in canonical order, where the number of
1004e00368fSchristos * entries is the sum of the counts in count[]. The decoding process can be
1014e00368fSchristos * seen in the function decode() below.
1024e00368fSchristos */
1034e00368fSchristos struct huffman {
1044e00368fSchristos short *count; /* number of symbols of each length */
1054e00368fSchristos short *symbol; /* canonically ordered symbols */
1064e00368fSchristos };
1074e00368fSchristos
1084e00368fSchristos /*
1094e00368fSchristos * Decode a code from the stream s using huffman table h. Return the symbol or
1104e00368fSchristos * a negative value if there is an error. If all of the lengths are zero, i.e.
1114e00368fSchristos * an empty code, or if the code is incomplete and an invalid code is received,
1124e00368fSchristos * then -9 is returned after reading MAXBITS bits.
1134e00368fSchristos *
1144e00368fSchristos * Format notes:
1154e00368fSchristos *
1164e00368fSchristos * - The codes as stored in the compressed data are bit-reversed relative to
1174e00368fSchristos * a simple integer ordering of codes of the same lengths. Hence below the
1184e00368fSchristos * bits are pulled from the compressed data one at a time and used to
1194e00368fSchristos * build the code value reversed from what is in the stream in order to
1204e00368fSchristos * permit simple integer comparisons for decoding.
1214e00368fSchristos *
1224e00368fSchristos * - The first code for the shortest length is all ones. Subsequent codes of
1234e00368fSchristos * the same length are simply integer decrements of the previous code. When
1244e00368fSchristos * moving up a length, a one bit is appended to the code. For a complete
1254e00368fSchristos * code, the last code of the longest length will be all zeros. To support
1264e00368fSchristos * this ordering, the bits pulled during decoding are inverted to apply the
1274e00368fSchristos * more "natural" ordering starting with all zeros and incrementing.
1284e00368fSchristos */
decode(struct state * s,struct huffman * h)1294e00368fSchristos local int decode(struct state *s, struct huffman *h)
1304e00368fSchristos {
1314e00368fSchristos int len; /* current number of bits in code */
1324e00368fSchristos int code; /* len bits being decoded */
1334e00368fSchristos int first; /* first code of length len */
1344e00368fSchristos int count; /* number of codes of length len */
1354e00368fSchristos int index; /* index of first code of length len in symbol table */
1364e00368fSchristos int bitbuf; /* bits from stream */
1374e00368fSchristos int left; /* bits left in next or left to process */
1384e00368fSchristos short *next; /* next number of codes */
1394e00368fSchristos
1404e00368fSchristos bitbuf = s->bitbuf;
1414e00368fSchristos left = s->bitcnt;
1424e00368fSchristos code = first = index = 0;
1434e00368fSchristos len = 1;
1444e00368fSchristos next = h->count + 1;
1454e00368fSchristos while (1) {
1464e00368fSchristos while (left--) {
1474e00368fSchristos code |= (bitbuf & 1) ^ 1; /* invert code */
1484e00368fSchristos bitbuf >>= 1;
1494e00368fSchristos count = *next++;
1504e00368fSchristos if (code < first + count) { /* if length len, return symbol */
1514e00368fSchristos s->bitbuf = bitbuf;
1524e00368fSchristos s->bitcnt = (s->bitcnt - len) & 7;
1534e00368fSchristos return h->symbol[index + (code - first)];
1544e00368fSchristos }
1554e00368fSchristos index += count; /* else update for next length */
1564e00368fSchristos first += count;
1574e00368fSchristos first <<= 1;
1584e00368fSchristos code <<= 1;
1594e00368fSchristos len++;
1604e00368fSchristos }
1614e00368fSchristos left = (MAXBITS+1) - len;
1624e00368fSchristos if (left == 0) break;
1634e00368fSchristos if (s->left == 0) {
1644e00368fSchristos s->left = s->infun(s->inhow, &(s->in));
1654e00368fSchristos if (s->left == 0) longjmp(s->env, 1); /* out of input */
1664e00368fSchristos }
1674e00368fSchristos bitbuf = *(s->in)++;
1684e00368fSchristos s->left--;
1694e00368fSchristos if (left > 8) left = 8;
1704e00368fSchristos }
1714e00368fSchristos return -9; /* ran out of codes */
1724e00368fSchristos }
1734e00368fSchristos
1744e00368fSchristos /*
1754e00368fSchristos * Given a list of repeated code lengths rep[0..n-1], where each byte is a
1764e00368fSchristos * count (high four bits + 1) and a code length (low four bits), generate the
1774e00368fSchristos * list of code lengths. This compaction reduces the size of the object code.
1784e00368fSchristos * Then given the list of code lengths length[0..n-1] representing a canonical
1794e00368fSchristos * Huffman code for n symbols, construct the tables required to decode those
1804e00368fSchristos * codes. Those tables are the number of codes of each length, and the symbols
1814e00368fSchristos * sorted by length, retaining their original order within each length. The
1824e00368fSchristos * return value is zero for a complete code set, negative for an over-
1834e00368fSchristos * subscribed code set, and positive for an incomplete code set. The tables
1844e00368fSchristos * can be used if the return value is zero or positive, but they cannot be used
1854e00368fSchristos * if the return value is negative. If the return value is zero, it is not
1864e00368fSchristos * possible for decode() using that table to return an error--any stream of
1874e00368fSchristos * enough bits will resolve to a symbol. If the return value is positive, then
1884e00368fSchristos * it is possible for decode() using that table to return an error for received
1894e00368fSchristos * codes past the end of the incomplete lengths.
1904e00368fSchristos */
construct(struct huffman * h,const unsigned char * rep,int n)1914e00368fSchristos local int construct(struct huffman *h, const unsigned char *rep, int n)
1924e00368fSchristos {
1934e00368fSchristos int symbol; /* current symbol when stepping through length[] */
1944e00368fSchristos int len; /* current length when stepping through h->count[] */
1954e00368fSchristos int left; /* number of possible codes left of current length */
1964e00368fSchristos short offs[MAXBITS+1]; /* offsets in symbol table for each length */
1974e00368fSchristos short length[256]; /* code lengths */
1984e00368fSchristos
1994e00368fSchristos /* convert compact repeat counts into symbol bit length list */
2004e00368fSchristos symbol = 0;
2014e00368fSchristos do {
2024e00368fSchristos len = *rep++;
2034e00368fSchristos left = (len >> 4) + 1;
2044e00368fSchristos len &= 15;
2054e00368fSchristos do {
2064e00368fSchristos length[symbol++] = len;
2074e00368fSchristos } while (--left);
2084e00368fSchristos } while (--n);
2094e00368fSchristos n = symbol;
2104e00368fSchristos
2114e00368fSchristos /* count number of codes of each length */
2124e00368fSchristos for (len = 0; len <= MAXBITS; len++)
2134e00368fSchristos h->count[len] = 0;
2144e00368fSchristos for (symbol = 0; symbol < n; symbol++)
2154e00368fSchristos (h->count[length[symbol]])++; /* assumes lengths are within bounds */
2164e00368fSchristos if (h->count[0] == n) /* no codes! */
2174e00368fSchristos return 0; /* complete, but decode() will fail */
2184e00368fSchristos
2194e00368fSchristos /* check for an over-subscribed or incomplete set of lengths */
2204e00368fSchristos left = 1; /* one possible code of zero length */
2214e00368fSchristos for (len = 1; len <= MAXBITS; len++) {
2224e00368fSchristos left <<= 1; /* one more bit, double codes left */
2234e00368fSchristos left -= h->count[len]; /* deduct count from possible codes */
2244e00368fSchristos if (left < 0) return left; /* over-subscribed--return negative */
2254e00368fSchristos } /* left > 0 means incomplete */
2264e00368fSchristos
2274e00368fSchristos /* generate offsets into symbol table for each length for sorting */
2284e00368fSchristos offs[1] = 0;
2294e00368fSchristos for (len = 1; len < MAXBITS; len++)
2304e00368fSchristos offs[len + 1] = offs[len] + h->count[len];
2314e00368fSchristos
2324e00368fSchristos /*
2334e00368fSchristos * put symbols in table sorted by length, by symbol order within each
2344e00368fSchristos * length
2354e00368fSchristos */
2364e00368fSchristos for (symbol = 0; symbol < n; symbol++)
2374e00368fSchristos if (length[symbol] != 0)
2384e00368fSchristos h->symbol[offs[length[symbol]]++] = symbol;
2394e00368fSchristos
2404e00368fSchristos /* return zero for complete set, positive for incomplete set */
2414e00368fSchristos return left;
2424e00368fSchristos }
2434e00368fSchristos
2444e00368fSchristos /*
2454e00368fSchristos * Decode PKWare Compression Library stream.
2464e00368fSchristos *
2474e00368fSchristos * Format notes:
2484e00368fSchristos *
2494e00368fSchristos * - First byte is 0 if literals are uncoded or 1 if they are coded. Second
2504e00368fSchristos * byte is 4, 5, or 6 for the number of extra bits in the distance code.
2514e00368fSchristos * This is the base-2 logarithm of the dictionary size minus six.
2524e00368fSchristos *
2534e00368fSchristos * - Compressed data is a combination of literals and length/distance pairs
2544e00368fSchristos * terminated by an end code. Literals are either Huffman coded or
2554e00368fSchristos * uncoded bytes. A length/distance pair is a coded length followed by a
2564e00368fSchristos * coded distance to represent a string that occurs earlier in the
2574e00368fSchristos * uncompressed data that occurs again at the current location.
2584e00368fSchristos *
2594e00368fSchristos * - A bit preceding a literal or length/distance pair indicates which comes
2604e00368fSchristos * next, 0 for literals, 1 for length/distance.
2614e00368fSchristos *
2624e00368fSchristos * - If literals are uncoded, then the next eight bits are the literal, in the
263*699b0f92Schristos * normal bit order in the stream, i.e. no bit-reversal is needed. Similarly,
2644e00368fSchristos * no bit reversal is needed for either the length extra bits or the distance
2654e00368fSchristos * extra bits.
2664e00368fSchristos *
2674e00368fSchristos * - Literal bytes are simply written to the output. A length/distance pair is
2684e00368fSchristos * an instruction to copy previously uncompressed bytes to the output. The
2694e00368fSchristos * copy is from distance bytes back in the output stream, copying for length
2704e00368fSchristos * bytes.
2714e00368fSchristos *
2724e00368fSchristos * - Distances pointing before the beginning of the output data are not
2734e00368fSchristos * permitted.
2744e00368fSchristos *
2754e00368fSchristos * - Overlapped copies, where the length is greater than the distance, are
2764e00368fSchristos * allowed and common. For example, a distance of one and a length of 518
2774e00368fSchristos * simply copies the last byte 518 times. A distance of four and a length of
2784e00368fSchristos * twelve copies the last four bytes three times. A simple forward copy
2794e00368fSchristos * ignoring whether the length is greater than the distance or not implements
2804e00368fSchristos * this correctly.
2814e00368fSchristos */
decomp(struct state * s)2824e00368fSchristos local int decomp(struct state *s)
2834e00368fSchristos {
2844e00368fSchristos int lit; /* true if literals are coded */
2854e00368fSchristos int dict; /* log2(dictionary size) - 6 */
2864e00368fSchristos int symbol; /* decoded symbol, extra bits for distance */
2874e00368fSchristos int len; /* length for copy */
288ed8eb4c2Schristos unsigned dist; /* distance for copy */
2894e00368fSchristos int copy; /* copy counter */
2904e00368fSchristos unsigned char *from, *to; /* copy pointers */
2914e00368fSchristos static int virgin = 1; /* build tables once */
2924e00368fSchristos static short litcnt[MAXBITS+1], litsym[256]; /* litcode memory */
2934e00368fSchristos static short lencnt[MAXBITS+1], lensym[16]; /* lencode memory */
2944e00368fSchristos static short distcnt[MAXBITS+1], distsym[64]; /* distcode memory */
2954e00368fSchristos static struct huffman litcode = {litcnt, litsym}; /* length code */
2964e00368fSchristos static struct huffman lencode = {lencnt, lensym}; /* length code */
2974e00368fSchristos static struct huffman distcode = {distcnt, distsym};/* distance code */
2984e00368fSchristos /* bit lengths of literal codes */
2994e00368fSchristos static const unsigned char litlen[] = {
3004e00368fSchristos 11, 124, 8, 7, 28, 7, 188, 13, 76, 4, 10, 8, 12, 10, 12, 10, 8, 23, 8,
3014e00368fSchristos 9, 7, 6, 7, 8, 7, 6, 55, 8, 23, 24, 12, 11, 7, 9, 11, 12, 6, 7, 22, 5,
3024e00368fSchristos 7, 24, 6, 11, 9, 6, 7, 22, 7, 11, 38, 7, 9, 8, 25, 11, 8, 11, 9, 12,
3034e00368fSchristos 8, 12, 5, 38, 5, 38, 5, 11, 7, 5, 6, 21, 6, 10, 53, 8, 7, 24, 10, 27,
3044e00368fSchristos 44, 253, 253, 253, 252, 252, 252, 13, 12, 45, 12, 45, 12, 61, 12, 45,
3054e00368fSchristos 44, 173};
3064e00368fSchristos /* bit lengths of length codes 0..15 */
3074e00368fSchristos static const unsigned char lenlen[] = {2, 35, 36, 53, 38, 23};
3084e00368fSchristos /* bit lengths of distance codes 0..63 */
3094e00368fSchristos static const unsigned char distlen[] = {2, 20, 53, 230, 247, 151, 248};
3104e00368fSchristos static const short base[16] = { /* base for length codes */
3114e00368fSchristos 3, 2, 4, 5, 6, 7, 8, 9, 10, 12, 16, 24, 40, 72, 136, 264};
3124e00368fSchristos static const char extra[16] = { /* extra bits for length codes */
3134e00368fSchristos 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8};
3144e00368fSchristos
3154e00368fSchristos /* set up decoding tables (once--might not be thread-safe) */
3164e00368fSchristos if (virgin) {
3174e00368fSchristos construct(&litcode, litlen, sizeof(litlen));
3184e00368fSchristos construct(&lencode, lenlen, sizeof(lenlen));
3194e00368fSchristos construct(&distcode, distlen, sizeof(distlen));
3204e00368fSchristos virgin = 0;
3214e00368fSchristos }
3224e00368fSchristos
3234e00368fSchristos /* read header */
3244e00368fSchristos lit = bits(s, 8);
3254e00368fSchristos if (lit > 1) return -1;
3264e00368fSchristos dict = bits(s, 8);
3274e00368fSchristos if (dict < 4 || dict > 6) return -2;
3284e00368fSchristos
3294e00368fSchristos /* decode literals and length/distance pairs */
3304e00368fSchristos do {
3314e00368fSchristos if (bits(s, 1)) {
3324e00368fSchristos /* get length */
3334e00368fSchristos symbol = decode(s, &lencode);
3344e00368fSchristos len = base[symbol] + bits(s, extra[symbol]);
3354e00368fSchristos if (len == 519) break; /* end code */
3364e00368fSchristos
3374e00368fSchristos /* get distance */
3384e00368fSchristos symbol = len == 2 ? 2 : dict;
3394e00368fSchristos dist = decode(s, &distcode) << symbol;
3404e00368fSchristos dist += bits(s, symbol);
3414e00368fSchristos dist++;
3424e00368fSchristos if (s->first && dist > s->next)
3434e00368fSchristos return -3; /* distance too far back */
3444e00368fSchristos
3454e00368fSchristos /* copy length bytes from distance bytes back */
3464e00368fSchristos do {
3474e00368fSchristos to = s->out + s->next;
3484e00368fSchristos from = to - dist;
3494e00368fSchristos copy = MAXWIN;
3504e00368fSchristos if (s->next < dist) {
3514e00368fSchristos from += copy;
3524e00368fSchristos copy = dist;
3534e00368fSchristos }
3544e00368fSchristos copy -= s->next;
3554e00368fSchristos if (copy > len) copy = len;
3564e00368fSchristos len -= copy;
3574e00368fSchristos s->next += copy;
3584e00368fSchristos do {
3594e00368fSchristos *to++ = *from++;
3604e00368fSchristos } while (--copy);
3614e00368fSchristos if (s->next == MAXWIN) {
3624e00368fSchristos if (s->outfun(s->outhow, s->out, s->next)) return 1;
3634e00368fSchristos s->next = 0;
3644e00368fSchristos s->first = 0;
3654e00368fSchristos }
3664e00368fSchristos } while (len != 0);
3674e00368fSchristos }
3684e00368fSchristos else {
3694e00368fSchristos /* get literal and write it */
3704e00368fSchristos symbol = lit ? decode(s, &litcode) : bits(s, 8);
3714e00368fSchristos s->out[s->next++] = symbol;
3724e00368fSchristos if (s->next == MAXWIN) {
3734e00368fSchristos if (s->outfun(s->outhow, s->out, s->next)) return 1;
3744e00368fSchristos s->next = 0;
3754e00368fSchristos s->first = 0;
3764e00368fSchristos }
3774e00368fSchristos }
3784e00368fSchristos } while (1);
3794e00368fSchristos return 0;
3804e00368fSchristos }
3814e00368fSchristos
3824e00368fSchristos /* See comments in blast.h */
blast(blast_in infun,void * inhow,blast_out outfun,void * outhow,unsigned * left,unsigned char ** in)383*699b0f92Schristos int blast(blast_in infun, void *inhow, blast_out outfun, void *outhow,
384*699b0f92Schristos unsigned *left, unsigned char **in)
3854e00368fSchristos {
3864e00368fSchristos struct state s; /* input/output state */
3874e00368fSchristos int err; /* return value */
3884e00368fSchristos
3894e00368fSchristos /* initialize input state */
3904e00368fSchristos s.infun = infun;
3914e00368fSchristos s.inhow = inhow;
392*699b0f92Schristos if (left != NULL && *left) {
393*699b0f92Schristos s.left = *left;
394*699b0f92Schristos s.in = *in;
395*699b0f92Schristos }
396*699b0f92Schristos else
3974e00368fSchristos s.left = 0;
3984e00368fSchristos s.bitbuf = 0;
3994e00368fSchristos s.bitcnt = 0;
4004e00368fSchristos
4014e00368fSchristos /* initialize output state */
4024e00368fSchristos s.outfun = outfun;
4034e00368fSchristos s.outhow = outhow;
4044e00368fSchristos s.next = 0;
4054e00368fSchristos s.first = 1;
4064e00368fSchristos
4074e00368fSchristos /* return if bits() or decode() tries to read past available input */
4084e00368fSchristos if (setjmp(s.env) != 0) /* if came back here via longjmp(), */
4094e00368fSchristos err = 2; /* then skip decomp(), return error */
4104e00368fSchristos else
4114e00368fSchristos err = decomp(&s); /* decompress */
4124e00368fSchristos
413*699b0f92Schristos /* return unused input */
414*699b0f92Schristos if (left != NULL)
415*699b0f92Schristos *left = s.left;
416*699b0f92Schristos if (in != NULL)
417*699b0f92Schristos *in = s.left ? s.in : NULL;
418*699b0f92Schristos
4194e00368fSchristos /* write any leftover output and update the error code if needed */
4204e00368fSchristos if (err != 1 && s.next && s.outfun(s.outhow, s.out, s.next) && err == 0)
4214e00368fSchristos err = 1;
4224e00368fSchristos return err;
4234e00368fSchristos }
4244e00368fSchristos
4254e00368fSchristos #ifdef TEST
4264e00368fSchristos /* Example of how to use blast() */
4274e00368fSchristos #include <stdio.h>
4284e00368fSchristos #include <stdlib.h>
4294e00368fSchristos
4304e00368fSchristos #define CHUNK 16384
4314e00368fSchristos
inf(void * how,unsigned char ** buf)4324e00368fSchristos local unsigned inf(void *how, unsigned char **buf)
4334e00368fSchristos {
4344e00368fSchristos static unsigned char hold[CHUNK];
4354e00368fSchristos
4364e00368fSchristos *buf = hold;
4374e00368fSchristos return fread(hold, 1, CHUNK, (FILE *)how);
4384e00368fSchristos }
4394e00368fSchristos
outf(void * how,unsigned char * buf,unsigned len)4404e00368fSchristos local int outf(void *how, unsigned char *buf, unsigned len)
4414e00368fSchristos {
4424e00368fSchristos return fwrite(buf, 1, len, (FILE *)how) != len;
4434e00368fSchristos }
4444e00368fSchristos
4454e00368fSchristos /* Decompress a PKWare Compression Library stream from stdin to stdout */
main(void)4464e00368fSchristos int main(void)
4474e00368fSchristos {
448*699b0f92Schristos int ret;
449*699b0f92Schristos unsigned left;
4504e00368fSchristos
4514e00368fSchristos /* decompress to stdout */
452*699b0f92Schristos left = 0;
453*699b0f92Schristos ret = blast(inf, stdin, outf, stdout, &left, NULL);
454*699b0f92Schristos if (ret != 0)
455*699b0f92Schristos fprintf(stderr, "blast error: %d\n", ret);
4564e00368fSchristos
457*699b0f92Schristos /* count any leftover bytes */
458*699b0f92Schristos while (getchar() != EOF)
459*699b0f92Schristos left++;
460*699b0f92Schristos if (left)
461*699b0f92Schristos fprintf(stderr, "blast warning: %u unused bytes of input\n", left);
4624e00368fSchristos
4634e00368fSchristos /* return blast() error code */
4644e00368fSchristos return ret;
4654e00368fSchristos }
4664e00368fSchristos #endif
467