vrshoot

diff libs/zlib/infback.c @ 0:b2f14e535253

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 01 Feb 2014 19:58:19 +0200
parents
children
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/libs/zlib/infback.c	Sat Feb 01 19:58:19 2014 +0200
     1.3 @@ -0,0 +1,623 @@
     1.4 +/* infback.c -- inflate using a call-back interface
     1.5 + * Copyright (C) 1995-2005 Mark Adler
     1.6 + * For conditions of distribution and use, see copyright notice in zlib.h
     1.7 + */
     1.8 +
     1.9 +/*
    1.10 +   This code is largely copied from inflate.c.  Normally either infback.o or
    1.11 +   inflate.o would be linked into an application--not both.  The interface
    1.12 +   with inffast.c is retained so that optimized assembler-coded versions of
    1.13 +   inflate_fast() can be used with either inflate.c or infback.c.
    1.14 + */
    1.15 +
    1.16 +#include "zutil.h"
    1.17 +#include "inftrees.h"
    1.18 +#include "inflate.h"
    1.19 +#include "inffast.h"
    1.20 +
    1.21 +/* function prototypes */
    1.22 +local void fixedtables OF((struct inflate_state FAR *state));
    1.23 +
    1.24 +/*
    1.25 +   strm provides memory allocation functions in zalloc and zfree, or
    1.26 +   Z_NULL to use the library memory allocation functions.
    1.27 +
    1.28 +   windowBits is in the range 8..15, and window is a user-supplied
    1.29 +   window and output buffer that is 2**windowBits bytes.
    1.30 + */
    1.31 +int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size)
    1.32 +z_streamp strm;
    1.33 +int windowBits;
    1.34 +unsigned char FAR *window;
    1.35 +const char *version;
    1.36 +int stream_size;
    1.37 +{
    1.38 +    struct inflate_state FAR *state;
    1.39 +
    1.40 +    if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
    1.41 +        stream_size != (int)(sizeof(z_stream)))
    1.42 +        return Z_VERSION_ERROR;
    1.43 +    if (strm == Z_NULL || window == Z_NULL ||
    1.44 +        windowBits < 8 || windowBits > 15)
    1.45 +        return Z_STREAM_ERROR;
    1.46 +    strm->msg = Z_NULL;                 /* in case we return an error */
    1.47 +    if (strm->zalloc == (alloc_func)0) {
    1.48 +        strm->zalloc = zcalloc;
    1.49 +        strm->opaque = (voidpf)0;
    1.50 +    }
    1.51 +    if (strm->zfree == (free_func)0) strm->zfree = zcfree;
    1.52 +    state = (struct inflate_state FAR *)ZALLOC(strm, 1,
    1.53 +                                               sizeof(struct inflate_state));
    1.54 +    if (state == Z_NULL) return Z_MEM_ERROR;
    1.55 +    Tracev((stderr, "inflate: allocated\n"));
    1.56 +    strm->state = (struct internal_state FAR *)state;
    1.57 +    state->dmax = 32768U;
    1.58 +    state->wbits = windowBits;
    1.59 +    state->wsize = 1U << windowBits;
    1.60 +    state->window = window;
    1.61 +    state->write = 0;
    1.62 +    state->whave = 0;
    1.63 +    return Z_OK;
    1.64 +}
    1.65 +
    1.66 +/*
    1.67 +   Return state with length and distance decoding tables and index sizes set to
    1.68 +   fixed code decoding.  Normally this returns fixed tables from inffixed.h.
    1.69 +   If BUILDFIXED is defined, then instead this routine builds the tables the
    1.70 +   first time it's called, and returns those tables the first time and
    1.71 +   thereafter.  This reduces the size of the code by about 2K bytes, in
    1.72 +   exchange for a little execution time.  However, BUILDFIXED should not be
    1.73 +   used for threaded applications, since the rewriting of the tables and virgin
    1.74 +   may not be thread-safe.
    1.75 + */
    1.76 +local void fixedtables(state)
    1.77 +struct inflate_state FAR *state;
    1.78 +{
    1.79 +#ifdef BUILDFIXED
    1.80 +    static int virgin = 1;
    1.81 +    static code *lenfix, *distfix;
    1.82 +    static code fixed[544];
    1.83 +
    1.84 +    /* build fixed huffman tables if first call (may not be thread safe) */
    1.85 +    if (virgin) {
    1.86 +        unsigned sym, bits;
    1.87 +        static code *next;
    1.88 +
    1.89 +        /* literal/length table */
    1.90 +        sym = 0;
    1.91 +        while (sym < 144) state->lens[sym++] = 8;
    1.92 +        while (sym < 256) state->lens[sym++] = 9;
    1.93 +        while (sym < 280) state->lens[sym++] = 7;
    1.94 +        while (sym < 288) state->lens[sym++] = 8;
    1.95 +        next = fixed;
    1.96 +        lenfix = next;
    1.97 +        bits = 9;
    1.98 +        inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
    1.99 +
   1.100 +        /* distance table */
   1.101 +        sym = 0;
   1.102 +        while (sym < 32) state->lens[sym++] = 5;
   1.103 +        distfix = next;
   1.104 +        bits = 5;
   1.105 +        inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
   1.106 +
   1.107 +        /* do this just once */
   1.108 +        virgin = 0;
   1.109 +    }
   1.110 +#else /* !BUILDFIXED */
   1.111 +#   include "inffixed.h"
   1.112 +#endif /* BUILDFIXED */
   1.113 +    state->lencode = lenfix;
   1.114 +    state->lenbits = 9;
   1.115 +    state->distcode = distfix;
   1.116 +    state->distbits = 5;
   1.117 +}
   1.118 +
   1.119 +/* Macros for inflateBack(): */
   1.120 +
   1.121 +/* Load returned state from inflate_fast() */
   1.122 +#define LOAD() \
   1.123 +    do { \
   1.124 +        put = strm->next_out; \
   1.125 +        left = strm->avail_out; \
   1.126 +        next = strm->next_in; \
   1.127 +        have = strm->avail_in; \
   1.128 +        hold = state->hold; \
   1.129 +        bits = state->bits; \
   1.130 +    } while (0)
   1.131 +
   1.132 +/* Set state from registers for inflate_fast() */
   1.133 +#define RESTORE() \
   1.134 +    do { \
   1.135 +        strm->next_out = put; \
   1.136 +        strm->avail_out = left; \
   1.137 +        strm->next_in = next; \
   1.138 +        strm->avail_in = have; \
   1.139 +        state->hold = hold; \
   1.140 +        state->bits = bits; \
   1.141 +    } while (0)
   1.142 +
   1.143 +/* Clear the input bit accumulator */
   1.144 +#define INITBITS() \
   1.145 +    do { \
   1.146 +        hold = 0; \
   1.147 +        bits = 0; \
   1.148 +    } while (0)
   1.149 +
   1.150 +/* Assure that some input is available.  If input is requested, but denied,
   1.151 +   then return a Z_BUF_ERROR from inflateBack(). */
   1.152 +#define PULL() \
   1.153 +    do { \
   1.154 +        if (have == 0) { \
   1.155 +            have = in(in_desc, &next); \
   1.156 +            if (have == 0) { \
   1.157 +                next = Z_NULL; \
   1.158 +                ret = Z_BUF_ERROR; \
   1.159 +                goto inf_leave; \
   1.160 +            } \
   1.161 +        } \
   1.162 +    } while (0)
   1.163 +
   1.164 +/* Get a byte of input into the bit accumulator, or return from inflateBack()
   1.165 +   with an error if there is no input available. */
   1.166 +#define PULLBYTE() \
   1.167 +    do { \
   1.168 +        PULL(); \
   1.169 +        have--; \
   1.170 +        hold += (unsigned long)(*next++) << bits; \
   1.171 +        bits += 8; \
   1.172 +    } while (0)
   1.173 +
   1.174 +/* Assure that there are at least n bits in the bit accumulator.  If there is
   1.175 +   not enough available input to do that, then return from inflateBack() with
   1.176 +   an error. */
   1.177 +#define NEEDBITS(n) \
   1.178 +    do { \
   1.179 +        while (bits < (unsigned)(n)) \
   1.180 +            PULLBYTE(); \
   1.181 +    } while (0)
   1.182 +
   1.183 +/* Return the low n bits of the bit accumulator (n < 16) */
   1.184 +#define BITS(n) \
   1.185 +    ((unsigned)hold & ((1U << (n)) - 1))
   1.186 +
   1.187 +/* Remove n bits from the bit accumulator */
   1.188 +#define DROPBITS(n) \
   1.189 +    do { \
   1.190 +        hold >>= (n); \
   1.191 +        bits -= (unsigned)(n); \
   1.192 +    } while (0)
   1.193 +
   1.194 +/* Remove zero to seven bits as needed to go to a byte boundary */
   1.195 +#define BYTEBITS() \
   1.196 +    do { \
   1.197 +        hold >>= bits & 7; \
   1.198 +        bits -= bits & 7; \
   1.199 +    } while (0)
   1.200 +
   1.201 +/* Assure that some output space is available, by writing out the window
   1.202 +   if it's full.  If the write fails, return from inflateBack() with a
   1.203 +   Z_BUF_ERROR. */
   1.204 +#define ROOM() \
   1.205 +    do { \
   1.206 +        if (left == 0) { \
   1.207 +            put = state->window; \
   1.208 +            left = state->wsize; \
   1.209 +            state->whave = left; \
   1.210 +            if (out(out_desc, put, left)) { \
   1.211 +                ret = Z_BUF_ERROR; \
   1.212 +                goto inf_leave; \
   1.213 +            } \
   1.214 +        } \
   1.215 +    } while (0)
   1.216 +
   1.217 +/*
   1.218 +   strm provides the memory allocation functions and window buffer on input,
   1.219 +   and provides information on the unused input on return.  For Z_DATA_ERROR
   1.220 +   returns, strm will also provide an error message.
   1.221 +
   1.222 +   in() and out() are the call-back input and output functions.  When
   1.223 +   inflateBack() needs more input, it calls in().  When inflateBack() has
   1.224 +   filled the window with output, or when it completes with data in the
   1.225 +   window, it calls out() to write out the data.  The application must not
   1.226 +   change the provided input until in() is called again or inflateBack()
   1.227 +   returns.  The application must not change the window/output buffer until
   1.228 +   inflateBack() returns.
   1.229 +
   1.230 +   in() and out() are called with a descriptor parameter provided in the
   1.231 +   inflateBack() call.  This parameter can be a structure that provides the
   1.232 +   information required to do the read or write, as well as accumulated
   1.233 +   information on the input and output such as totals and check values.
   1.234 +
   1.235 +   in() should return zero on failure.  out() should return non-zero on
   1.236 +   failure.  If either in() or out() fails, than inflateBack() returns a
   1.237 +   Z_BUF_ERROR.  strm->next_in can be checked for Z_NULL to see whether it
   1.238 +   was in() or out() that caused in the error.  Otherwise,  inflateBack()
   1.239 +   returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format
   1.240 +   error, or Z_MEM_ERROR if it could not allocate memory for the state.
   1.241 +   inflateBack() can also return Z_STREAM_ERROR if the input parameters
   1.242 +   are not correct, i.e. strm is Z_NULL or the state was not initialized.
   1.243 + */
   1.244 +int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc)
   1.245 +z_streamp strm;
   1.246 +in_func in;
   1.247 +void FAR *in_desc;
   1.248 +out_func out;
   1.249 +void FAR *out_desc;
   1.250 +{
   1.251 +    struct inflate_state FAR *state;
   1.252 +    unsigned char FAR *next;    /* next input */
   1.253 +    unsigned char FAR *put;     /* next output */
   1.254 +    unsigned have, left;        /* available input and output */
   1.255 +    unsigned long hold;         /* bit buffer */
   1.256 +    unsigned bits;              /* bits in bit buffer */
   1.257 +    unsigned copy;              /* number of stored or match bytes to copy */
   1.258 +    unsigned char FAR *from;    /* where to copy match bytes from */
   1.259 +    code this;                  /* current decoding table entry */
   1.260 +    code last;                  /* parent table entry */
   1.261 +    unsigned len;               /* length to copy for repeats, bits to drop */
   1.262 +    int ret;                    /* return code */
   1.263 +    static const unsigned short order[19] = /* permutation of code lengths */
   1.264 +        {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
   1.265 +
   1.266 +    /* Check that the strm exists and that the state was initialized */
   1.267 +    if (strm == Z_NULL || strm->state == Z_NULL)
   1.268 +        return Z_STREAM_ERROR;
   1.269 +    state = (struct inflate_state FAR *)strm->state;
   1.270 +
   1.271 +    /* Reset the state */
   1.272 +    strm->msg = Z_NULL;
   1.273 +    state->mode = TYPE;
   1.274 +    state->last = 0;
   1.275 +    state->whave = 0;
   1.276 +    next = strm->next_in;
   1.277 +    have = next != Z_NULL ? strm->avail_in : 0;
   1.278 +    hold = 0;
   1.279 +    bits = 0;
   1.280 +    put = state->window;
   1.281 +    left = state->wsize;
   1.282 +
   1.283 +    /* Inflate until end of block marked as last */
   1.284 +    for (;;)
   1.285 +        switch (state->mode) {
   1.286 +        case TYPE:
   1.287 +            /* determine and dispatch block type */
   1.288 +            if (state->last) {
   1.289 +                BYTEBITS();
   1.290 +                state->mode = DONE;
   1.291 +                break;
   1.292 +            }
   1.293 +            NEEDBITS(3);
   1.294 +            state->last = BITS(1);
   1.295 +            DROPBITS(1);
   1.296 +            switch (BITS(2)) {
   1.297 +            case 0:                             /* stored block */
   1.298 +                Tracev((stderr, "inflate:     stored block%s\n",
   1.299 +                        state->last ? " (last)" : ""));
   1.300 +                state->mode = STORED;
   1.301 +                break;
   1.302 +            case 1:                             /* fixed block */
   1.303 +                fixedtables(state);
   1.304 +                Tracev((stderr, "inflate:     fixed codes block%s\n",
   1.305 +                        state->last ? " (last)" : ""));
   1.306 +                state->mode = LEN;              /* decode codes */
   1.307 +                break;
   1.308 +            case 2:                             /* dynamic block */
   1.309 +                Tracev((stderr, "inflate:     dynamic codes block%s\n",
   1.310 +                        state->last ? " (last)" : ""));
   1.311 +                state->mode = TABLE;
   1.312 +                break;
   1.313 +            case 3:
   1.314 +                strm->msg = (char *)"invalid block type";
   1.315 +                state->mode = BAD;
   1.316 +            }
   1.317 +            DROPBITS(2);
   1.318 +            break;
   1.319 +
   1.320 +        case STORED:
   1.321 +            /* get and verify stored block length */
   1.322 +            BYTEBITS();                         /* go to byte boundary */
   1.323 +            NEEDBITS(32);
   1.324 +            if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
   1.325 +                strm->msg = (char *)"invalid stored block lengths";
   1.326 +                state->mode = BAD;
   1.327 +                break;
   1.328 +            }
   1.329 +            state->length = (unsigned)hold & 0xffff;
   1.330 +            Tracev((stderr, "inflate:       stored length %u\n",
   1.331 +                    state->length));
   1.332 +            INITBITS();
   1.333 +
   1.334 +            /* copy stored block from input to output */
   1.335 +            while (state->length != 0) {
   1.336 +                copy = state->length;
   1.337 +                PULL();
   1.338 +                ROOM();
   1.339 +                if (copy > have) copy = have;
   1.340 +                if (copy > left) copy = left;
   1.341 +                zmemcpy(put, next, copy);
   1.342 +                have -= copy;
   1.343 +                next += copy;
   1.344 +                left -= copy;
   1.345 +                put += copy;
   1.346 +                state->length -= copy;
   1.347 +            }
   1.348 +            Tracev((stderr, "inflate:       stored end\n"));
   1.349 +            state->mode = TYPE;
   1.350 +            break;
   1.351 +
   1.352 +        case TABLE:
   1.353 +            /* get dynamic table entries descriptor */
   1.354 +            NEEDBITS(14);
   1.355 +            state->nlen = BITS(5) + 257;
   1.356 +            DROPBITS(5);
   1.357 +            state->ndist = BITS(5) + 1;
   1.358 +            DROPBITS(5);
   1.359 +            state->ncode = BITS(4) + 4;
   1.360 +            DROPBITS(4);
   1.361 +#ifndef PKZIP_BUG_WORKAROUND
   1.362 +            if (state->nlen > 286 || state->ndist > 30) {
   1.363 +                strm->msg = (char *)"too many length or distance symbols";
   1.364 +                state->mode = BAD;
   1.365 +                break;
   1.366 +            }
   1.367 +#endif
   1.368 +            Tracev((stderr, "inflate:       table sizes ok\n"));
   1.369 +
   1.370 +            /* get code length code lengths (not a typo) */
   1.371 +            state->have = 0;
   1.372 +            while (state->have < state->ncode) {
   1.373 +                NEEDBITS(3);
   1.374 +                state->lens[order[state->have++]] = (unsigned short)BITS(3);
   1.375 +                DROPBITS(3);
   1.376 +            }
   1.377 +            while (state->have < 19)
   1.378 +                state->lens[order[state->have++]] = 0;
   1.379 +            state->next = state->codes;
   1.380 +            state->lencode = (code const FAR *)(state->next);
   1.381 +            state->lenbits = 7;
   1.382 +            ret = inflate_table(CODES, state->lens, 19, &(state->next),
   1.383 +                                &(state->lenbits), state->work);
   1.384 +            if (ret) {
   1.385 +                strm->msg = (char *)"invalid code lengths set";
   1.386 +                state->mode = BAD;
   1.387 +                break;
   1.388 +            }
   1.389 +            Tracev((stderr, "inflate:       code lengths ok\n"));
   1.390 +
   1.391 +            /* get length and distance code code lengths */
   1.392 +            state->have = 0;
   1.393 +            while (state->have < state->nlen + state->ndist) {
   1.394 +                for (;;) {
   1.395 +                    this = state->lencode[BITS(state->lenbits)];
   1.396 +                    if ((unsigned)(this.bits) <= bits) break;
   1.397 +                    PULLBYTE();
   1.398 +                }
   1.399 +                if (this.val < 16) {
   1.400 +                    NEEDBITS(this.bits);
   1.401 +                    DROPBITS(this.bits);
   1.402 +                    state->lens[state->have++] = this.val;
   1.403 +                }
   1.404 +                else {
   1.405 +                    if (this.val == 16) {
   1.406 +                        NEEDBITS(this.bits + 2);
   1.407 +                        DROPBITS(this.bits);
   1.408 +                        if (state->have == 0) {
   1.409 +                            strm->msg = (char *)"invalid bit length repeat";
   1.410 +                            state->mode = BAD;
   1.411 +                            break;
   1.412 +                        }
   1.413 +                        len = (unsigned)(state->lens[state->have - 1]);
   1.414 +                        copy = 3 + BITS(2);
   1.415 +                        DROPBITS(2);
   1.416 +                    }
   1.417 +                    else if (this.val == 17) {
   1.418 +                        NEEDBITS(this.bits + 3);
   1.419 +                        DROPBITS(this.bits);
   1.420 +                        len = 0;
   1.421 +                        copy = 3 + BITS(3);
   1.422 +                        DROPBITS(3);
   1.423 +                    }
   1.424 +                    else {
   1.425 +                        NEEDBITS(this.bits + 7);
   1.426 +                        DROPBITS(this.bits);
   1.427 +                        len = 0;
   1.428 +                        copy = 11 + BITS(7);
   1.429 +                        DROPBITS(7);
   1.430 +                    }
   1.431 +                    if (state->have + copy > state->nlen + state->ndist) {
   1.432 +                        strm->msg = (char *)"invalid bit length repeat";
   1.433 +                        state->mode = BAD;
   1.434 +                        break;
   1.435 +                    }
   1.436 +                    while (copy--)
   1.437 +                        state->lens[state->have++] = (unsigned short)len;
   1.438 +                }
   1.439 +            }
   1.440 +
   1.441 +            /* handle error breaks in while */
   1.442 +            if (state->mode == BAD) break;
   1.443 +
   1.444 +            /* build code tables */
   1.445 +            state->next = state->codes;
   1.446 +            state->lencode = (code const FAR *)(state->next);
   1.447 +            state->lenbits = 9;
   1.448 +            ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
   1.449 +                                &(state->lenbits), state->work);
   1.450 +            if (ret) {
   1.451 +                strm->msg = (char *)"invalid literal/lengths set";
   1.452 +                state->mode = BAD;
   1.453 +                break;
   1.454 +            }
   1.455 +            state->distcode = (code const FAR *)(state->next);
   1.456 +            state->distbits = 6;
   1.457 +            ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
   1.458 +                            &(state->next), &(state->distbits), state->work);
   1.459 +            if (ret) {
   1.460 +                strm->msg = (char *)"invalid distances set";
   1.461 +                state->mode = BAD;
   1.462 +                break;
   1.463 +            }
   1.464 +            Tracev((stderr, "inflate:       codes ok\n"));
   1.465 +            state->mode = LEN;
   1.466 +
   1.467 +        case LEN:
   1.468 +            /* use inflate_fast() if we have enough input and output */
   1.469 +            if (have >= 6 && left >= 258) {
   1.470 +                RESTORE();
   1.471 +                if (state->whave < state->wsize)
   1.472 +                    state->whave = state->wsize - left;
   1.473 +                inflate_fast(strm, state->wsize);
   1.474 +                LOAD();
   1.475 +                break;
   1.476 +            }
   1.477 +
   1.478 +            /* get a literal, length, or end-of-block code */
   1.479 +            for (;;) {
   1.480 +                this = state->lencode[BITS(state->lenbits)];
   1.481 +                if ((unsigned)(this.bits) <= bits) break;
   1.482 +                PULLBYTE();
   1.483 +            }
   1.484 +            if (this.op && (this.op & 0xf0) == 0) {
   1.485 +                last = this;
   1.486 +                for (;;) {
   1.487 +                    this = state->lencode[last.val +
   1.488 +                            (BITS(last.bits + last.op) >> last.bits)];
   1.489 +                    if ((unsigned)(last.bits + this.bits) <= bits) break;
   1.490 +                    PULLBYTE();
   1.491 +                }
   1.492 +                DROPBITS(last.bits);
   1.493 +            }
   1.494 +            DROPBITS(this.bits);
   1.495 +            state->length = (unsigned)this.val;
   1.496 +
   1.497 +            /* process literal */
   1.498 +            if (this.op == 0) {
   1.499 +                Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
   1.500 +                        "inflate:         literal '%c'\n" :
   1.501 +                        "inflate:         literal 0x%02x\n", this.val));
   1.502 +                ROOM();
   1.503 +                *put++ = (unsigned char)(state->length);
   1.504 +                left--;
   1.505 +                state->mode = LEN;
   1.506 +                break;
   1.507 +            }
   1.508 +
   1.509 +            /* process end of block */
   1.510 +            if (this.op & 32) {
   1.511 +                Tracevv((stderr, "inflate:         end of block\n"));
   1.512 +                state->mode = TYPE;
   1.513 +                break;
   1.514 +            }
   1.515 +
   1.516 +            /* invalid code */
   1.517 +            if (this.op & 64) {
   1.518 +                strm->msg = (char *)"invalid literal/length code";
   1.519 +                state->mode = BAD;
   1.520 +                break;
   1.521 +            }
   1.522 +
   1.523 +            /* length code -- get extra bits, if any */
   1.524 +            state->extra = (unsigned)(this.op) & 15;
   1.525 +            if (state->extra != 0) {
   1.526 +                NEEDBITS(state->extra);
   1.527 +                state->length += BITS(state->extra);
   1.528 +                DROPBITS(state->extra);
   1.529 +            }
   1.530 +            Tracevv((stderr, "inflate:         length %u\n", state->length));
   1.531 +
   1.532 +            /* get distance code */
   1.533 +            for (;;) {
   1.534 +                this = state->distcode[BITS(state->distbits)];
   1.535 +                if ((unsigned)(this.bits) <= bits) break;
   1.536 +                PULLBYTE();
   1.537 +            }
   1.538 +            if ((this.op & 0xf0) == 0) {
   1.539 +                last = this;
   1.540 +                for (;;) {
   1.541 +                    this = state->distcode[last.val +
   1.542 +                            (BITS(last.bits + last.op) >> last.bits)];
   1.543 +                    if ((unsigned)(last.bits + this.bits) <= bits) break;
   1.544 +                    PULLBYTE();
   1.545 +                }
   1.546 +                DROPBITS(last.bits);
   1.547 +            }
   1.548 +            DROPBITS(this.bits);
   1.549 +            if (this.op & 64) {
   1.550 +                strm->msg = (char *)"invalid distance code";
   1.551 +                state->mode = BAD;
   1.552 +                break;
   1.553 +            }
   1.554 +            state->offset = (unsigned)this.val;
   1.555 +
   1.556 +            /* get distance extra bits, if any */
   1.557 +            state->extra = (unsigned)(this.op) & 15;
   1.558 +            if (state->extra != 0) {
   1.559 +                NEEDBITS(state->extra);
   1.560 +                state->offset += BITS(state->extra);
   1.561 +                DROPBITS(state->extra);
   1.562 +            }
   1.563 +            if (state->offset > state->wsize - (state->whave < state->wsize ?
   1.564 +                                                left : 0)) {
   1.565 +                strm->msg = (char *)"invalid distance too far back";
   1.566 +                state->mode = BAD;
   1.567 +                break;
   1.568 +            }
   1.569 +            Tracevv((stderr, "inflate:         distance %u\n", state->offset));
   1.570 +
   1.571 +            /* copy match from window to output */
   1.572 +            do {
   1.573 +                ROOM();
   1.574 +                copy = state->wsize - state->offset;
   1.575 +                if (copy < left) {
   1.576 +                    from = put + copy;
   1.577 +                    copy = left - copy;
   1.578 +                }
   1.579 +                else {
   1.580 +                    from = put - state->offset;
   1.581 +                    copy = left;
   1.582 +                }
   1.583 +                if (copy > state->length) copy = state->length;
   1.584 +                state->length -= copy;
   1.585 +                left -= copy;
   1.586 +                do {
   1.587 +                    *put++ = *from++;
   1.588 +                } while (--copy);
   1.589 +            } while (state->length != 0);
   1.590 +            break;
   1.591 +
   1.592 +        case DONE:
   1.593 +            /* inflate stream terminated properly -- write leftover output */
   1.594 +            ret = Z_STREAM_END;
   1.595 +            if (left < state->wsize) {
   1.596 +                if (out(out_desc, state->window, state->wsize - left))
   1.597 +                    ret = Z_BUF_ERROR;
   1.598 +            }
   1.599 +            goto inf_leave;
   1.600 +
   1.601 +        case BAD:
   1.602 +            ret = Z_DATA_ERROR;
   1.603 +            goto inf_leave;
   1.604 +
   1.605 +        default:                /* can't happen, but makes compilers happy */
   1.606 +            ret = Z_STREAM_ERROR;
   1.607 +            goto inf_leave;
   1.608 +        }
   1.609 +
   1.610 +    /* Return unused input */
   1.611 +  inf_leave:
   1.612 +    strm->next_in = next;
   1.613 +    strm->avail_in = have;
   1.614 +    return ret;
   1.615 +}
   1.616 +
   1.617 +int ZEXPORT inflateBackEnd(strm)
   1.618 +z_streamp strm;
   1.619 +{
   1.620 +    if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
   1.621 +        return Z_STREAM_ERROR;
   1.622 +    ZFREE(strm, strm->state);
   1.623 +    strm->state = Z_NULL;
   1.624 +    Tracev((stderr, "inflate: end\n"));
   1.625 +    return Z_OK;
   1.626 +}