1/* infcodes.c -- process literals and length/distance pairs
2 * Copyright (C) 1995-1998 Mark Adler
3 * For conditions of distribution and use, see copyright notice in zlib.h
4 */
5
6#include <linux/zutil.h>
7#include "inftrees.h"
8#include "infblock.h"
9#include "infcodes.h"
10#include "infutil.h"
11#include "inffast.h"
12
13/* simplify the use of the inflate_huft type with some defines */
14#define exop word.what.Exop
15#define bits word.what.Bits
16
17inflate_codes_statef *zlib_inflate_codes_new(bl, bd, tl, td, z)
18uInt bl, bd;
19inflate_huft *tl;
20inflate_huft *td; /* need separate declaration for Borland C++ */
21z_streamp z;
22{
23  inflate_codes_statef *c;
24
25  c = &WS(z)->working_state;
26  {
27    c->mode = START;
28    c->lbits = (Byte)bl;
29    c->dbits = (Byte)bd;
30    c->ltree = tl;
31    c->dtree = td;
32  }
33  return c;
34}
35
36
37int zlib_inflate_codes(s, z, r)
38inflate_blocks_statef *s;
39z_streamp z;
40int r;
41{
42  uInt j;               /* temporary storage */
43  inflate_huft *t;      /* temporary pointer */
44  uInt e;               /* extra bits or operation */
45  uLong b;              /* bit buffer */
46  uInt k;               /* bits in bit buffer */
47  Bytef *p;             /* input data pointer */
48  uInt n;               /* bytes available there */
49  Bytef *q;             /* output window write pointer */
50  uInt m;               /* bytes to end of window or read pointer */
51  Bytef *f;             /* pointer to copy strings from */
52  inflate_codes_statef *c = s->sub.decode.codes;  /* codes state */
53
54  /* copy input/output information to locals (UPDATE macro restores) */
55  LOAD
56
57  /* process input and output based on current state */
58  while (1) switch (c->mode)
59  {             /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
60    case START:         /* x: set up for LEN */
61#ifndef SLOW
62      if (m >= 258 && n >= 10)
63      {
64        UPDATE
65        r = zlib_inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);
66        LOAD
67        if (r != Z_OK)
68        {
69          c->mode = r == Z_STREAM_END ? WASH : BADCODE;
70          break;
71        }
72      }
73#endif /* !SLOW */
74      c->sub.code.need = c->lbits;
75      c->sub.code.tree = c->ltree;
76      c->mode = LEN;
77    case LEN:           /* i: get length/literal/eob next */
78      j = c->sub.code.need;
79      NEEDBITS(j)
80      t = c->sub.code.tree + ((uInt)b & zlib_inflate_mask[j]);
81      DUMPBITS(t->bits)
82      e = (uInt)(t->exop);
83      if (e == 0)               /* literal */
84      {
85        c->sub.lit = t->base;
86        c->mode = LIT;
87        break;
88      }
89      if (e & 16)               /* length */
90      {
91        c->sub.copy.get = e & 15;
92        c->len = t->base;
93        c->mode = LENEXT;
94        break;
95      }
96      if ((e & 64) == 0)        /* next table */
97      {
98        c->sub.code.need = e;
99        c->sub.code.tree = t + t->base;
100        break;
101      }
102      if (e & 32)               /* end of block */
103      {
104        c->mode = WASH;
105        break;
106      }
107      c->mode = BADCODE;        /* invalid code */
108      z->msg = (char*)"invalid literal/length code";
109      r = Z_DATA_ERROR;
110      LEAVE
111    case LENEXT:        /* i: getting length extra (have base) */
112      j = c->sub.copy.get;
113      NEEDBITS(j)
114      c->len += (uInt)b & zlib_inflate_mask[j];
115      DUMPBITS(j)
116      c->sub.code.need = c->dbits;
117      c->sub.code.tree = c->dtree;
118      c->mode = DIST;
119    case DIST:          /* i: get distance next */
120      j = c->sub.code.need;
121      NEEDBITS(j)
122      t = c->sub.code.tree + ((uInt)b & zlib_inflate_mask[j]);
123      DUMPBITS(t->bits)
124      e = (uInt)(t->exop);
125      if (e & 16)               /* distance */
126      {
127        c->sub.copy.get = e & 15;
128        c->sub.copy.dist = t->base;
129        c->mode = DISTEXT;
130        break;
131      }
132      if ((e & 64) == 0)        /* next table */
133      {
134        c->sub.code.need = e;
135        c->sub.code.tree = t + t->base;
136        break;
137      }
138      c->mode = BADCODE;        /* invalid code */
139      z->msg = (char*)"invalid distance code";
140      r = Z_DATA_ERROR;
141      LEAVE
142    case DISTEXT:       /* i: getting distance extra */
143      j = c->sub.copy.get;
144      NEEDBITS(j)
145      c->sub.copy.dist += (uInt)b & zlib_inflate_mask[j];
146      DUMPBITS(j)
147      c->mode = COPY;
148    case COPY:          /* o: copying bytes in window, waiting for space */
149#ifndef __TURBOC__     /* Turbo C bug for following expression */
150      f = (uInt)(q - s->window) < c->sub.copy.dist ?
151          s->end - (c->sub.copy.dist - (q - s->window)) :
152          q - c->sub.copy.dist;
153#else
154      f = q - c->sub.copy.dist;
155      if ((uInt)(q - s->window) < c->sub.copy.dist)
156        f = s->end - (c->sub.copy.dist - (uInt)(q - s->window));
157#endif
158      while (c->len)
159      {
160        NEEDOUT
161        OUTBYTE(*f++)
162        if (f == s->end)
163          f = s->window;
164        c->len--;
165      }
166      c->mode = START;
167      break;
168    case LIT:           /* o: got literal, waiting for output space */
169      NEEDOUT
170      OUTBYTE(c->sub.lit)
171      c->mode = START;
172      break;
173    case WASH:          /* o: got eob, possibly more output */
174      if (k > 7)        /* return unused byte, if any */
175      {
176        k -= 8;
177        n++;
178        p--;            /* can always return one */
179      }
180      FLUSH
181      if (s->read != s->write)
182        LEAVE
183      c->mode = END;
184    case END:
185      r = Z_STREAM_END;
186      LEAVE
187    case BADCODE:       /* x: got error */
188      r = Z_DATA_ERROR;
189      LEAVE
190    default:
191      r = Z_STREAM_ERROR;
192      LEAVE
193  }
194#ifdef NEED_DUMMY_RETURN
195  return Z_STREAM_ERROR;  /* Some dumb compilers complain without this */
196#endif
197}
198
199
200void zlib_inflate_codes_free(c, z)
201inflate_codes_statef *c;
202z_streamp z;
203{
204}
205