if ((uInt)(q - s->window) < c->sub.copy.dist) f = s->end - (c->sub.copy.dist - (uInt)(q - s->window)); #endif
while (f < s->window)              f += s->end - s->window;
int inflate_codes(s, z, r)inflate_blocks_statef *s;z_streamp z;int r;{  uInt j;               /* temporary storage */  inflate_huft *t;      /* temporary pointer */  uInt e;               /* extra bits or operation */  uLong b;              /* bit buffer */  uInt k;               /* bits in bit buffer */  Bytef *p;             /* input data pointer */  uInt n;               /* bytes available there */  Bytef *q;             /* output window write pointer */  uInt m;               /* bytes to end of window or read pointer */  Bytef *f;             /* pointer to copy strings from */  inflate_codes_statef *c = s->sub.decode.codes;  /* codes state */  /* copy input/output information to locals (UPDATE macro restores) */  LOAD  /* process input and output based on current state */  while (1) switch (c->mode)  {             /* waiting for "i:"=input, "o:"=output, "x:"=nothing */    case START:         /* x: set up for LEN */#ifndef SLOW      if (m >= 258 && n >= 10)      {        UPDATE        r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);        LOAD        if (r != Z_OK)        {          c->mode = r == Z_STREAM_END ? WASH : BADCODE;          break;        }      }#endif /* !SLOW */      c->sub.code.need = c->lbits;      c->sub.code.tree = c->ltree;      c->mode = LEN;    case LEN:           /* i: get length/literal/eob next */      j = c->sub.code.need;      NEEDBITS(j)      t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);      DUMPBITS(t->bits)      e = (uInt)(t->exop);      if (e == 0)               /* literal */      {        c->sub.lit = t->base;        Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?                 "inflate:         literal '%c'\n" :                 "inflate:         literal 0x%02x\n", t->base));        c->mode = LIT;        break;      }      if (e & 16)               /* length */      {        c->sub.copy.get = e & 15;        c->len = t->base;        c->mode = LENEXT;        break;      }      if ((e & 64) == 0)        /* next table */      {        c->sub.code.need = e;        c->sub.code.tree = t->next;        break;      }      if (e & 32)               /* end of block */      {        Tracevv((stderr, "inflate:         end of block\n"));        c->mode = WASH;        break;      }      c->mode = BADCODE;        /* invalid code */      z->msg = (char*)"invalid literal/length code";      r = Z_DATA_ERROR;      LEAVE    case LENEXT:        /* i: getting length extra (have base) */      j = c->sub.copy.get;      NEEDBITS(j)      c->len += (uInt)b & inflate_mask[j];      DUMPBITS(j)      c->sub.code.need = c->dbits;      c->sub.code.tree = c->dtree;      Tracevv((stderr, "inflate:         length %u\n", c->len));      c->mode = DIST;    case DIST:          /* i: get distance next */      j = c->sub.code.need;      NEEDBITS(j)      t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);      DUMPBITS(t->bits)      e = (uInt)(t->exop);      if (e & 16)               /* distance */      {        c->sub.copy.get = e & 15;        c->sub.copy.dist = t->base;        c->mode = DISTEXT;        break;      }      if ((e & 64) == 0)        /* next table */      {        c->sub.code.need = e;        c->sub.code.tree = t->next;        break;      }      c->mode = BADCODE;        /* invalid code */      z->msg = (char*)"invalid distance code";      r = Z_DATA_ERROR;      LEAVE    case DISTEXT:       /* i: getting distance extra */      j = c->sub.copy.get;      NEEDBITS(j)      c->sub.copy.dist += (uInt)b & inflate_mask[j];      DUMPBITS(j)      Tracevv((stderr, "inflate:         distance %u\n", c->sub.copy.dist));      c->mode = COPY;    case COPY:          /* o: copying bytes in window, waiting for space */#ifndef __TURBOC__ /* Turbo C bug for following expression */      f = (uInt)(q - s->window) < c->sub.copy.dist ?          s->end - (c->sub.copy.dist - (q - s->window)) :          q - c->sub.copy.dist;#else      f = q - c->sub.copy.dist;      if ((uInt)(q - s->window) < c->sub.copy.dist)        f = s->end - (c->sub.copy.dist - (uInt)(q - s->window));#endif      while (c->len)      {        NEEDOUT        OUTBYTE(*f++)        if (f == s->end)          f = s->window;        c->len--;      }      c->mode = START;      break;    case LIT:           /* o: got literal, waiting for output space */      NEEDOUT      OUTBYTE(c->sub.lit)      c->mode = START;      break;    case WASH:          /* o: got eob, possibly more output */      FLUSH      if (s->read != s->write)        LEAVE      c->mode = END;    case END:      r = Z_STREAM_END;      LEAVE    case BADCODE:       /* x: got error */      r = Z_DATA_ERROR;      LEAVE    default:      r = Z_STREAM_ERROR;      LEAVE  }}