Fossil SCM

fossil-scm / compat / zlib / contrib / blast / blast.c
Source Blame History 422 lines
7ef7284… drh 1 /* blast.c
e38d5e1… jan.nijtmans 2 * Copyright (C) 2003, 2012, 2013 Mark Adler
7ef7284… drh 3 * For conditions of distribution and use, see copyright notice in blast.h
e38d5e1… jan.nijtmans 4 * version 1.3, 24 Aug 2013
7ef7284… drh 5 *
7ef7284… drh 6 * blast.c decompresses data compressed by the PKWare Compression Library.
7ef7284… drh 7 * This function provides functionality similar to the explode() function of
7ef7284… drh 8 * the PKWare library, hence the name "blast".
7ef7284… drh 9 *
7ef7284… drh 10 * This decompressor is based on the excellent format description provided by
7ef7284… drh 11 * Ben Rudiak-Gould in comp.compression on August 13, 2001. Interestingly, the
7ef7284… drh 12 * example Ben provided in the post is incorrect. The distance 110001 should
7ef7284… drh 13 * instead be 111000. When corrected, the example byte stream becomes:
7ef7284… drh 14 *
7ef7284… drh 15 * 00 04 82 24 25 8f 80 7f
7ef7284… drh 16 *
7ef7284… drh 17 * which decompresses to "AIAIAIAIAIAIA" (without the quotes).
7ef7284… drh 18 */
7ef7284… drh 19
7ef7284… drh 20 /*
7ef7284… drh 21 * Change history:
7ef7284… drh 22 *
7ef7284… drh 23 * 1.0 12 Feb 2003 - First version
7ef7284… drh 24 * 1.1 16 Feb 2003 - Fixed distance check for > 4 GB uncompressed data
bb4776e… jan.nijtmans 25 * 1.2 24 Oct 2012 - Add note about using binary mode in stdio
bb4776e… jan.nijtmans 26 * - Fix comparisons of differently signed integers
e38d5e1… jan.nijtmans 27 * 1.3 24 Aug 2013 - Return unused input from blast()
e38d5e1… jan.nijtmans 28 * - Fix test code to correctly report unused input
e38d5e1… jan.nijtmans 29 * - Enable the provision of initial input to blast()
7ef7284… drh 30 */
7ef7284… drh 31
e38d5e1… jan.nijtmans 32 #include <stddef.h> /* for NULL */
7ef7284… drh 33 #include <setjmp.h> /* for setjmp(), longjmp(), and jmp_buf */
7ef7284… drh 34 #include "blast.h" /* prototype for blast() */
7ef7284… drh 35
7ef7284… drh 36 #define MAXBITS 13 /* maximum code length */
7ef7284… drh 37 #define MAXWIN 4096 /* maximum window size */
7ef7284… drh 38
7ef7284… drh 39 /* input and output state */
7ef7284… drh 40 struct state {
7ef7284… drh 41 /* input state */
7ef7284… drh 42 blast_in infun; /* input function provided by user */
7ef7284… drh 43 void *inhow; /* opaque information passed to infun() */
7ef7284… drh 44 unsigned char *in; /* next input location */
7ef7284… drh 45 unsigned left; /* available input at in */
7ef7284… drh 46 int bitbuf; /* bit buffer */
7ef7284… drh 47 int bitcnt; /* number of bits in bit buffer */
7ef7284… drh 48
7ef7284… drh 49 /* input limit error return state for bits() and decode() */
7ef7284… drh 50 jmp_buf env;
7ef7284… drh 51
7ef7284… drh 52 /* output state */
7ef7284… drh 53 blast_out outfun; /* output function provided by user */
7ef7284… drh 54 void *outhow; /* opaque information passed to outfun() */
7ef7284… drh 55 unsigned next; /* index of next write location in out[] */
7ef7284… drh 56 int first; /* true to check distances (for first 4K) */
7ef7284… drh 57 unsigned char out[MAXWIN]; /* output buffer and sliding window */
7ef7284… drh 58 };
7ef7284… drh 59
7ef7284… drh 60 /*
7ef7284… drh 61 * Return need bits from the input stream. This always leaves less than
7ef7284… drh 62 * eight bits in the buffer. bits() works properly for need == 0.
7ef7284… drh 63 *
7ef7284… drh 64 * Format notes:
7ef7284… drh 65 *
7ef7284… drh 66 * - Bits are stored in bytes from the least significant bit to the most
7ef7284… drh 67 * significant bit. Therefore bits are dropped from the bottom of the bit
7ef7284… drh 68 * buffer, using shift right, and new bytes are appended to the top of the
7ef7284… drh 69 * bit buffer, using shift left.
7ef7284… drh 70 */
7ef7284… drh 71 local int bits(struct state *s, int need)
7ef7284… drh 72 {
7ef7284… drh 73 int val; /* bit accumulator */
7ef7284… drh 74
7ef7284… drh 75 /* load at least need bits into val */
7ef7284… drh 76 val = s->bitbuf;
7ef7284… drh 77 while (s->bitcnt < need) {
7ef7284… drh 78 if (s->left == 0) {
7ef7284… drh 79 s->left = s->infun(s->inhow, &(s->in));
7ef7284… drh 80 if (s->left == 0) longjmp(s->env, 1); /* out of input */
7ef7284… drh 81 }
7ef7284… drh 82 val |= (int)(*(s->in)++) << s->bitcnt; /* load eight bits */
7ef7284… drh 83 s->left--;
7ef7284… drh 84 s->bitcnt += 8;
7ef7284… drh 85 }
7ef7284… drh 86
7ef7284… drh 87 /* drop need bits and update buffer, always zero to seven bits left */
7ef7284… drh 88 s->bitbuf = val >> need;
7ef7284… drh 89 s->bitcnt -= need;
7ef7284… drh 90
7ef7284… drh 91 /* return need bits, zeroing the bits above that */
7ef7284… drh 92 return val & ((1 << need) - 1);
7ef7284… drh 93 }
7ef7284… drh 94
7ef7284… drh 95 /*
7ef7284… drh 96 * Huffman code decoding tables. count[1..MAXBITS] is the number of symbols of
7ef7284… drh 97 * each length, which for a canonical code are stepped through in order.
7ef7284… drh 98 * symbol[] are the symbol values in canonical order, where the number of
7ef7284… drh 99 * entries is the sum of the counts in count[]. The decoding process can be
7ef7284… drh 100 * seen in the function decode() below.
7ef7284… drh 101 */
7ef7284… drh 102 struct huffman {
7ef7284… drh 103 short *count; /* number of symbols of each length */
7ef7284… drh 104 short *symbol; /* canonically ordered symbols */
7ef7284… drh 105 };
7ef7284… drh 106
7ef7284… drh 107 /*
7ef7284… drh 108 * Decode a code from the stream s using huffman table h. Return the symbol or
7ef7284… drh 109 * a negative value if there is an error. If all of the lengths are zero, i.e.
7ef7284… drh 110 * an empty code, or if the code is incomplete and an invalid code is received,
7ef7284… drh 111 * then -9 is returned after reading MAXBITS bits.
7ef7284… drh 112 *
7ef7284… drh 113 * Format notes:
7ef7284… drh 114 *
7ef7284… drh 115 * - The codes as stored in the compressed data are bit-reversed relative to
7ef7284… drh 116 * a simple integer ordering of codes of the same lengths. Hence below the
7ef7284… drh 117 * bits are pulled from the compressed data one at a time and used to
7ef7284… drh 118 * build the code value reversed from what is in the stream in order to
7ef7284… drh 119 * permit simple integer comparisons for decoding.
7ef7284… drh 120 *
7ef7284… drh 121 * - The first code for the shortest length is all ones. Subsequent codes of
7ef7284… drh 122 * the same length are simply integer decrements of the previous code. When
7ef7284… drh 123 * moving up a length, a one bit is appended to the code. For a complete
7ef7284… drh 124 * code, the last code of the longest length will be all zeros. To support
7ef7284… drh 125 * this ordering, the bits pulled during decoding are inverted to apply the
7ef7284… drh 126 * more "natural" ordering starting with all zeros and incrementing.
7ef7284… drh 127 */
7ef7284… drh 128 local int decode(struct state *s, struct huffman *h)
7ef7284… drh 129 {
7ef7284… drh 130 int len; /* current number of bits in code */
7ef7284… drh 131 int code; /* len bits being decoded */
7ef7284… drh 132 int first; /* first code of length len */
7ef7284… drh 133 int count; /* number of codes of length len */
7ef7284… drh 134 int index; /* index of first code of length len in symbol table */
7ef7284… drh 135 int bitbuf; /* bits from stream */
7ef7284… drh 136 int left; /* bits left in next or left to process */
7ef7284… drh 137 short *next; /* next number of codes */
7ef7284… drh 138
7ef7284… drh 139 bitbuf = s->bitbuf;
7ef7284… drh 140 left = s->bitcnt;
7ef7284… drh 141 code = first = index = 0;
7ef7284… drh 142 len = 1;
7ef7284… drh 143 next = h->count + 1;
7ef7284… drh 144 while (1) {
7ef7284… drh 145 while (left--) {
7ef7284… drh 146 code |= (bitbuf & 1) ^ 1; /* invert code */
7ef7284… drh 147 bitbuf >>= 1;
7ef7284… drh 148 count = *next++;
7ef7284… drh 149 if (code < first + count) { /* if length len, return symbol */
7ef7284… drh 150 s->bitbuf = bitbuf;
7ef7284… drh 151 s->bitcnt = (s->bitcnt - len) & 7;
7ef7284… drh 152 return h->symbol[index + (code - first)];
7ef7284… drh 153 }
7ef7284… drh 154 index += count; /* else update for next length */
7ef7284… drh 155 first += count;
7ef7284… drh 156 first <<= 1;
7ef7284… drh 157 code <<= 1;
7ef7284… drh 158 len++;
7ef7284… drh 159 }
7ef7284… drh 160 left = (MAXBITS+1) - len;
7ef7284… drh 161 if (left == 0) break;
7ef7284… drh 162 if (s->left == 0) {
7ef7284… drh 163 s->left = s->infun(s->inhow, &(s->in));
7ef7284… drh 164 if (s->left == 0) longjmp(s->env, 1); /* out of input */
7ef7284… drh 165 }
7ef7284… drh 166 bitbuf = *(s->in)++;
7ef7284… drh 167 s->left--;
7ef7284… drh 168 if (left > 8) left = 8;
7ef7284… drh 169 }
7ef7284… drh 170 return -9; /* ran out of codes */
7ef7284… drh 171 }
7ef7284… drh 172
7ef7284… drh 173 /*
7ef7284… drh 174 * Given a list of repeated code lengths rep[0..n-1], where each byte is a
7ef7284… drh 175 * count (high four bits + 1) and a code length (low four bits), generate the
7ef7284… drh 176 * list of code lengths. This compaction reduces the size of the object code.
7ef7284… drh 177 * Then given the list of code lengths length[0..n-1] representing a canonical
7ef7284… drh 178 * Huffman code for n symbols, construct the tables required to decode those
7ef7284… drh 179 * codes. Those tables are the number of codes of each length, and the symbols
7ef7284… drh 180 * sorted by length, retaining their original order within each length. The
7ef7284… drh 181 * return value is zero for a complete code set, negative for an over-
7ef7284… drh 182 * subscribed code set, and positive for an incomplete code set. The tables
7ef7284… drh 183 * can be used if the return value is zero or positive, but they cannot be used
7ef7284… drh 184 * if the return value is negative. If the return value is zero, it is not
7ef7284… drh 185 * possible for decode() using that table to return an error--any stream of
7ef7284… drh 186 * enough bits will resolve to a symbol. If the return value is positive, then
7ef7284… drh 187 * it is possible for decode() using that table to return an error for received
7ef7284… drh 188 * codes past the end of the incomplete lengths.
7ef7284… drh 189 */
7ef7284… drh 190 local int construct(struct huffman *h, const unsigned char *rep, int n)
7ef7284… drh 191 {
7ef7284… drh 192 int symbol; /* current symbol when stepping through length[] */
7ef7284… drh 193 int len; /* current length when stepping through h->count[] */
7ef7284… drh 194 int left; /* number of possible codes left of current length */
7ef7284… drh 195 short offs[MAXBITS+1]; /* offsets in symbol table for each length */
7ef7284… drh 196 short length[256]; /* code lengths */
7ef7284… drh 197
7ef7284… drh 198 /* convert compact repeat counts into symbol bit length list */
7ef7284… drh 199 symbol = 0;
7ef7284… drh 200 do {
7ef7284… drh 201 len = *rep++;
7ef7284… drh 202 left = (len >> 4) + 1;
7ef7284… drh 203 len &= 15;
7ef7284… drh 204 do {
7ef7284… drh 205 length[symbol++] = len;
7ef7284… drh 206 } while (--left);
7ef7284… drh 207 } while (--n);
7ef7284… drh 208 n = symbol;
7ef7284… drh 209
7ef7284… drh 210 /* count number of codes of each length */
7ef7284… drh 211 for (len = 0; len <= MAXBITS; len++)
7ef7284… drh 212 h->count[len] = 0;
7ef7284… drh 213 for (symbol = 0; symbol < n; symbol++)
7ef7284… drh 214 (h->count[length[symbol]])++; /* assumes lengths are within bounds */
7ef7284… drh 215 if (h->count[0] == n) /* no codes! */
7ef7284… drh 216 return 0; /* complete, but decode() will fail */
7ef7284… drh 217
7ef7284… drh 218 /* check for an over-subscribed or incomplete set of lengths */
7ef7284… drh 219 left = 1; /* one possible code of zero length */
7ef7284… drh 220 for (len = 1; len <= MAXBITS; len++) {
7ef7284… drh 221 left <<= 1; /* one more bit, double codes left */
7ef7284… drh 222 left -= h->count[len]; /* deduct count from possible codes */
7ef7284… drh 223 if (left < 0) return left; /* over-subscribed--return negative */
7ef7284… drh 224 } /* left > 0 means incomplete */
7ef7284… drh 225
7ef7284… drh 226 /* generate offsets into symbol table for each length for sorting */
7ef7284… drh 227 offs[1] = 0;
7ef7284… drh 228 for (len = 1; len < MAXBITS; len++)
7ef7284… drh 229 offs[len + 1] = offs[len] + h->count[len];
7ef7284… drh 230
7ef7284… drh 231 /*
7ef7284… drh 232 * put symbols in table sorted by length, by symbol order within each
7ef7284… drh 233 * length
7ef7284… drh 234 */
7ef7284… drh 235 for (symbol = 0; symbol < n; symbol++)
7ef7284… drh 236 if (length[symbol] != 0)
7ef7284… drh 237 h->symbol[offs[length[symbol]]++] = symbol;
7ef7284… drh 238
7ef7284… drh 239 /* return zero for complete set, positive for incomplete set */
7ef7284… drh 240 return left;
7ef7284… drh 241 }
7ef7284… drh 242
7ef7284… drh 243 /*
7ef7284… drh 244 * Decode PKWare Compression Library stream.
7ef7284… drh 245 *
7ef7284… drh 246 * Format notes:
7ef7284… drh 247 *
7ef7284… drh 248 * - First byte is 0 if literals are uncoded or 1 if they are coded. Second
7ef7284… drh 249 * byte is 4, 5, or 6 for the number of extra bits in the distance code.
7ef7284… drh 250 * This is the base-2 logarithm of the dictionary size minus six.
7ef7284… drh 251 *
7ef7284… drh 252 * - Compressed data is a combination of literals and length/distance pairs
7ef7284… drh 253 * terminated by an end code. Literals are either Huffman coded or
7ef7284… drh 254 * uncoded bytes. A length/distance pair is a coded length followed by a
7ef7284… drh 255 * coded distance to represent a string that occurs earlier in the
7ef7284… drh 256 * uncompressed data that occurs again at the current location.
7ef7284… drh 257 *
7ef7284… drh 258 * - A bit preceding a literal or length/distance pair indicates which comes
7ef7284… drh 259 * next, 0 for literals, 1 for length/distance.
7ef7284… drh 260 *
7ef7284… drh 261 * - If literals are uncoded, then the next eight bits are the literal, in the
e38d5e1… jan.nijtmans 262 * normal bit order in the stream, i.e. no bit-reversal is needed. Similarly,
7ef7284… drh 263 * no bit reversal is needed for either the length extra bits or the distance
7ef7284… drh 264 * extra bits.
7ef7284… drh 265 *
7ef7284… drh 266 * - Literal bytes are simply written to the output. A length/distance pair is
7ef7284… drh 267 * an instruction to copy previously uncompressed bytes to the output. The
7ef7284… drh 268 * copy is from distance bytes back in the output stream, copying for length
7ef7284… drh 269 * bytes.
7ef7284… drh 270 *
7ef7284… drh 271 * - Distances pointing before the beginning of the output data are not
7ef7284… drh 272 * permitted.
7ef7284… drh 273 *
7ef7284… drh 274 * - Overlapped copies, where the length is greater than the distance, are
7ef7284… drh 275 * allowed and common. For example, a distance of one and a length of 518
7ef7284… drh 276 * simply copies the last byte 518 times. A distance of four and a length of
7ef7284… drh 277 * twelve copies the last four bytes three times. A simple forward copy
7ef7284… drh 278 * ignoring whether the length is greater than the distance or not implements
7ef7284… drh 279 * this correctly.
7ef7284… drh 280 */
7ef7284… drh 281 local int decomp(struct state *s)
7ef7284… drh 282 {
7ef7284… drh 283 int lit; /* true if literals are coded */
7ef7284… drh 284 int dict; /* log2(dictionary size) - 6 */
7ef7284… drh 285 int symbol; /* decoded symbol, extra bits for distance */
7ef7284… drh 286 int len; /* length for copy */
bb4776e… jan.nijtmans 287 unsigned dist; /* distance for copy */
7ef7284… drh 288 int copy; /* copy counter */
7ef7284… drh 289 unsigned char *from, *to; /* copy pointers */
7ef7284… drh 290 static int virgin = 1; /* build tables once */
7ef7284… drh 291 static short litcnt[MAXBITS+1], litsym[256]; /* litcode memory */
7ef7284… drh 292 static short lencnt[MAXBITS+1], lensym[16]; /* lencode memory */
7ef7284… drh 293 static short distcnt[MAXBITS+1], distsym[64]; /* distcode memory */
7ef7284… drh 294 static struct huffman litcode = {litcnt, litsym}; /* length code */
7ef7284… drh 295 static struct huffman lencode = {lencnt, lensym}; /* length code */
7ef7284… drh 296 static struct huffman distcode = {distcnt, distsym};/* distance code */
7ef7284… drh 297 /* bit lengths of literal codes */
7ef7284… drh 298 static const unsigned char litlen[] = {
7ef7284… drh 299 11, 124, 8, 7, 28, 7, 188, 13, 76, 4, 10, 8, 12, 10, 12, 10, 8, 23, 8,
7ef7284… drh 300 9, 7, 6, 7, 8, 7, 6, 55, 8, 23, 24, 12, 11, 7, 9, 11, 12, 6, 7, 22, 5,
7ef7284… drh 301 7, 24, 6, 11, 9, 6, 7, 22, 7, 11, 38, 7, 9, 8, 25, 11, 8, 11, 9, 12,
7ef7284… drh 302 8, 12, 5, 38, 5, 38, 5, 11, 7, 5, 6, 21, 6, 10, 53, 8, 7, 24, 10, 27,
7ef7284… drh 303 44, 253, 253, 253, 252, 252, 252, 13, 12, 45, 12, 45, 12, 61, 12, 45,
7ef7284… drh 304 44, 173};
7ef7284… drh 305 /* bit lengths of length codes 0..15 */
7ef7284… drh 306 static const unsigned char lenlen[] = {2, 35, 36, 53, 38, 23};
7ef7284… drh 307 /* bit lengths of distance codes 0..63 */
7ef7284… drh 308 static const unsigned char distlen[] = {2, 20, 53, 230, 247, 151, 248};
7ef7284… drh 309 static const short base[16] = { /* base for length codes */
7ef7284… drh 310 3, 2, 4, 5, 6, 7, 8, 9, 10, 12, 16, 24, 40, 72, 136, 264};
7ef7284… drh 311 static const char extra[16] = { /* extra bits for length codes */
7ef7284… drh 312 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8};
7ef7284… drh 313
7ef7284… drh 314 /* set up decoding tables (once--might not be thread-safe) */
7ef7284… drh 315 if (virgin) {
7ef7284… drh 316 construct(&litcode, litlen, sizeof(litlen));
7ef7284… drh 317 construct(&lencode, lenlen, sizeof(lenlen));
7ef7284… drh 318 construct(&distcode, distlen, sizeof(distlen));
7ef7284… drh 319 virgin = 0;
7ef7284… drh 320 }
7ef7284… drh 321
7ef7284… drh 322 /* read header */
7ef7284… drh 323 lit = bits(s, 8);
7ef7284… drh 324 if (lit > 1) return -1;
7ef7284… drh 325 dict = bits(s, 8);
7ef7284… drh 326 if (dict < 4 || dict > 6) return -2;
7ef7284… drh 327
7ef7284… drh 328 /* decode literals and length/distance pairs */
7ef7284… drh 329 do {
7ef7284… drh 330 if (bits(s, 1)) {
7ef7284… drh 331 /* get length */
7ef7284… drh 332 symbol = decode(s, &lencode);
7ef7284… drh 333 len = base[symbol] + bits(s, extra[symbol]);
7ef7284… drh 334 if (len == 519) break; /* end code */
7ef7284… drh 335
7ef7284… drh 336 /* get distance */
7ef7284… drh 337 symbol = len == 2 ? 2 : dict;
7ef7284… drh 338 dist = decode(s, &distcode) << symbol;
7ef7284… drh 339 dist += bits(s, symbol);
7ef7284… drh 340 dist++;
7ef7284… drh 341 if (s->first && dist > s->next)
7ef7284… drh 342 return -3; /* distance too far back */
7ef7284… drh 343
7ef7284… drh 344 /* copy length bytes from distance bytes back */
7ef7284… drh 345 do {
7ef7284… drh 346 to = s->out + s->next;
7ef7284… drh 347 from = to - dist;
7ef7284… drh 348 copy = MAXWIN;
7ef7284… drh 349 if (s->next < dist) {
7ef7284… drh 350 from += copy;
7ef7284… drh 351 copy = dist;
7ef7284… drh 352 }
7ef7284… drh 353 copy -= s->next;
7ef7284… drh 354 if (copy > len) copy = len;
7ef7284… drh 355 len -= copy;
7ef7284… drh 356 s->next += copy;
7ef7284… drh 357 do {
7ef7284… drh 358 *to++ = *from++;
7ef7284… drh 359 } while (--copy);
7ef7284… drh 360 if (s->next == MAXWIN) {
7ef7284… drh 361 if (s->outfun(s->outhow, s->out, s->next)) return 1;
7ef7284… drh 362 s->next = 0;
7ef7284… drh 363 s->first = 0;
7ef7284… drh 364 }
7ef7284… drh 365 } while (len != 0);
7ef7284… drh 366 }
7ef7284… drh 367 else {
7ef7284… drh 368 /* get literal and write it */
7ef7284… drh 369 symbol = lit ? decode(s, &litcode) : bits(s, 8);
7ef7284… drh 370 s->out[s->next++] = symbol;
7ef7284… drh 371 if (s->next == MAXWIN) {
7ef7284… drh 372 if (s->outfun(s->outhow, s->out, s->next)) return 1;
7ef7284… drh 373 s->next = 0;
7ef7284… drh 374 s->first = 0;
7ef7284… drh 375 }
7ef7284… drh 376 }
7ef7284… drh 377 } while (1);
7ef7284… drh 378 return 0;
7ef7284… drh 379 }
7ef7284… drh 380
7ef7284… drh 381 /* See comments in blast.h */
e38d5e1… jan.nijtmans 382 int blast(blast_in infun, void *inhow, blast_out outfun, void *outhow,
e38d5e1… jan.nijtmans 383 unsigned *left, unsigned char **in)
7ef7284… drh 384 {
7ef7284… drh 385 struct state s; /* input/output state */
7ef7284… drh 386 int err; /* return value */
7ef7284… drh 387
7ef7284… drh 388 /* initialize input state */
7ef7284… drh 389 s.infun = infun;
7ef7284… drh 390 s.inhow = inhow;
e38d5e1… jan.nijtmans 391 if (left != NULL && *left) {
e38d5e1… jan.nijtmans 392 s.left = *left;
e38d5e1… jan.nijtmans 393 s.in = *in;
e38d5e1… jan.nijtmans 394 }
e38d5e1… jan.nijtmans 395 else
e38d5e1… jan.nijtmans 396 s.left = 0;
7ef7284… drh 397 s.bitbuf = 0;
7ef7284… drh 398 s.bitcnt = 0;
7ef7284… drh 399
7ef7284… drh 400 /* initialize output state */
7ef7284… drh 401 s.outfun = outfun;
7ef7284… drh 402 s.outhow = outhow;
7ef7284… drh 403 s.next = 0;
7ef7284… drh 404 s.first = 1;
7ef7284… drh 405
7ef7284… drh 406 /* return if bits() or decode() tries to read past available input */
7ef7284… drh 407 if (setjmp(s.env) != 0) /* if came back here via longjmp(), */
7ef7284… drh 408 err = 2; /* then skip decomp(), return error */
7ef7284… drh 409 else
7ef7284… drh 410 err = decomp(&s); /* decompress */
7ef7284… drh 411
e38d5e1… jan.nijtmans 412 /* return unused input */
e38d5e1… jan.nijtmans 413 if (left != NULL)
e38d5e1… jan.nijtmans 414 *left = s.left;
e38d5e1… jan.nijtmans 415 if (in != NULL)
e38d5e1… jan.nijtmans 416 *in = s.left ? s.in : NULL;
e38d5e1… jan.nijtmans 417
7ef7284… drh 418 /* write any leftover output and update the error code if needed */
7ef7284… drh 419 if (err != 1 && s.next && s.outfun(s.outhow, s.out, s.next) && err == 0)
7ef7284… drh 420 err = 1;
7ef7284… drh 421 return err;
7ef7284… drh 422 }

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button