ReactOS  0.4.14-dev-41-g31d7680
infcodes.c
Go to the documentation of this file.
1 /* infcodes.c -- process literals and length/distance pairs
2  * Copyright (C) 1995-2002 Mark Adler
3  * For conditions of distribution and use, see copyright notice in zlib.h
4  */
5 
6 #include "zutil.h"
7 #include "inftrees.h"
8 #include "infblock.h"
9 #include "infcodes.h"
10 #include "infutil.h"
11 
12 /* simplify the use of the inflate_huft type with some defines */
13 #define exop word.what.Exop
14 #define bits word.what.Bits
15 
16 typedef enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
17  START, /* x: set up for LEN */
18  LEN, /* i: get length/literal/eob next */
19  LENEXT, /* i: getting length extra (have base) */
20  DIST, /* i: get distance next */
21  DISTEXT, /* i: getting distance extra */
22  COPY, /* o: copying bytes in window, waiting for space */
23  LIT, /* o: got literal, waiting for output space */
24  WASH, /* o: got eob, possibly still output waiting */
25  END, /* x: got eob and all data flushed */
26  BADCODE} /* x: got error */
28 
29 /* inflate codes private state */
31 
32  /* mode */
33  inflate_codes_mode mode; /* current inflate_codes mode */
34 
35  /* mode dependent information */
37  union {
38  struct {
39  inflate_huft *tree; /* pointer into tree */
40  uInt need; /* bits needed */
41  } code; /* if LEN or DIST, where in tree */
42  uInt lit; /* if LIT, literal */
43  struct {
44  uInt get; /* bits to get for extra */
45  uInt dist; /* distance back to copy from */
46  } copy; /* if EXT or COPY, where and how much */
47  } sub; /* submode */
48 
49  /* mode independent information */
50  Byte lbits; /* ltree bits decoded per branch */
51  Byte dbits; /* dtree bits decoder per branch */
52  inflate_huft *ltree; /* literal/length/eob tree */
53  inflate_huft *dtree; /* distance tree */
54 
55 };
56 
57 
58 local inflate_codes_statef *inflate_codes_new( /* bl, bd, tl, td, z) */
59 uInt bl, uInt bd,
60 inflate_huft *tl,
61 inflate_huft *td, /* need separate declaration for Borland C++ */
62 z_streamp z )
63 {
65 
66  if ((c = (inflate_codes_statef *)
67  ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL)
68  {
69  c->mode = START;
70  c->lbits = (Byte)bl;
71  c->dbits = (Byte)bd;
72  c->ltree = tl;
73  c->dtree = td;
74  Tracev((stderr, "inflate: codes new\n"));
75  }
76  return c;
77 }
78 
79 
80 local int inflate_codes( /* s, z, r) */
82 z_streamp z,
83 int r )
84 {
85  uInt j; /* temporary storage */
86  inflate_huft *t; /* temporary pointer */
87  uInt e; /* extra bits or operation */
88  uLong b; /* bit buffer */
89  uInt k; /* bits in bit buffer */
90  Bytef *p; /* input data pointer */
91  uInt n; /* bytes available there */
92  Bytef *q; /* output window write pointer */
93  uInt m; /* bytes to end of window or read pointer */
94  Bytef *f; /* pointer to copy strings from */
95  inflate_codes_statef *c = s->sub.decode.codes; /* codes state */
96 
97  /* copy input/output information to locals (UPDATE macro restores) */
98  LOAD
99 
100  /* process input and output based on current state */
101  while (1) switch (c->mode)
102  { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
103  case START: /* x: set up for LEN */
104 #ifndef SLOW
105  if (m >= 258 && n >= 10)
106  {
107  UPDATE
108  r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);
109  LOAD
110  if (r != Z_OK)
111  {
112  c->mode = r == Z_STREAM_END ? WASH : BADCODE;
113  break;
114  }
115  }
116 #endif /* !SLOW */
117  c->sub.code.need = c->lbits;
118  c->sub.code.tree = c->ltree;
119  c->mode = LEN;
120  case LEN: /* i: get length/literal/eob next */
121  j = c->sub.code.need;
122  NEEDBITS(j)
123  t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
124  DUMPBITS(t->bits)
125  e = (uInt)(t->exop);
126  if (e == 0) /* literal */
127  {
128  c->sub.lit = t->base;
129  Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
130  "inflate: literal '%c'\n" :
131  "inflate: literal 0x%02x\n", t->base));
132  c->mode = LIT;
133  break;
134  }
135  if (e & 16) /* length */
136  {
137  c->sub.copy.get = e & 15;
138  c->len = t->base;
139  c->mode = LENEXT;
140  break;
141  }
142  if ((e & 64) == 0) /* next table */
143  {
144  c->sub.code.need = e;
145  c->sub.code.tree = t + t->base;
146  break;
147  }
148  if (e & 32) /* end of block */
149  {
150  Tracevv((stderr, "inflate: end of block\n"));
151  c->mode = WASH;
152  break;
153  }
154  c->mode = BADCODE; /* invalid code */
155  z->msg = (char*)"invalid literal/length code";
156  r = Z_DATA_ERROR;
157  LEAVE
158  case LENEXT: /* i: getting length extra (have base) */
159  j = c->sub.copy.get;
160  NEEDBITS(j)
161  c->len += (uInt)b & inflate_mask[j];
162  DUMPBITS(j)
163  c->sub.code.need = c->dbits;
164  c->sub.code.tree = c->dtree;
165  Tracevv((stderr, "inflate: length %u\n", c->len));
166  c->mode = DIST;
167  case DIST: /* i: get distance next */
168  j = c->sub.code.need;
169  NEEDBITS(j)
170  t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
171  DUMPBITS(t->bits)
172  e = (uInt)(t->exop);
173  if (e & 16) /* distance */
174  {
175  c->sub.copy.get = e & 15;
176  c->sub.copy.dist = t->base;
177  c->mode = DISTEXT;
178  break;
179  }
180  if ((e & 64) == 0) /* next table */
181  {
182  c->sub.code.need = e;
183  c->sub.code.tree = t + t->base;
184  break;
185  }
186  c->mode = BADCODE; /* invalid code */
187  z->msg = (char*)"invalid distance code";
188  r = Z_DATA_ERROR;
189  LEAVE
190  case DISTEXT: /* i: getting distance extra */
191  j = c->sub.copy.get;
192  NEEDBITS(j)
193  c->sub.copy.dist += (uInt)b & inflate_mask[j];
194  DUMPBITS(j)
195  Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist));
196  c->mode = COPY;
197  case COPY: /* o: copying bytes in window, waiting for space */
198  f = q - c->sub.copy.dist;
199  while (f < s->window) /* modulo window size-"while" instead */
200  f += s->end - s->window; /* of "if" handles invalid distances */
201  while (c->len)
202  {
203  NEEDOUT
204  OUTBYTE(*f++)
205  if (f == s->end)
206  f = s->window;
207  c->len--;
208  }
209  c->mode = START;
210  break;
211  case LIT: /* o: got literal, waiting for output space */
212  NEEDOUT
213  OUTBYTE(c->sub.lit)
214  c->mode = START;
215  break;
216  case WASH: /* o: got eob, possibly more output */
217  if (k > 7) /* return unused byte, if any */
218  {
219  Assert(k < 16, "inflate_codes grabbed too many bytes")
220  k -= 8;
221  n++;
222  p--; /* can always return one */
223  }
224  FLUSH
225  if (s->read != s->write)
226  LEAVE
227  c->mode = END;
228  case END:
229  r = Z_STREAM_END;
230  LEAVE
231  case BADCODE: /* x: got error */
232  r = Z_DATA_ERROR;
233  LEAVE
234  default:
235  r = Z_STREAM_ERROR;
236  LEAVE
237  }
238 #ifdef NEED_DUMMY_RETURN
239  return Z_STREAM_ERROR; /* Some dumb compilers complain without this */
240 #endif
241 }
242 
243 
244 local void inflate_codes_free( /* c, z) */
246 z_streamp z )
247 {
248  ZFREE(z, c);
249  Tracev((stderr, "inflate: codes free\n"));
250 }
Definition: infcodes.c:24
struct inflate_blocks_state FAR inflate_blocks_statef
Definition: infblock.h:15
inflate_codes_mode
Definition: infcodes.c:16
unsigned char Byte
Definition: zconf.h:391
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
#define ZALLOC(strm, items, size)
Definition: zutil.h:210
Definition: infcodes.c:22
#define LEAVE
Definition: classpnp.h:112
GLdouble n
Definition: glext.h:7729
struct inflate_codes_state::@3843::@3845 copy
GLdouble GLdouble t
Definition: gl.h:2047
Definition: infcodes.c:20
inflate_codes_mode mode
Definition: infcodes.c:33
struct inflate_codes_state::@3843::@3844 code
#define NEEDBITS(j)
Definition: infutil.h:75
inflate_huft * ltree
Definition: infcodes.c:52
#define Z_STREAM_ERROR
Definition: zlib.h:181
#define NEEDOUT
Definition: infutil.h:82
#define UPDATE
Definition: infutil.h:69
const GLfloat * m
Definition: glext.h:10848
#define Z_STREAM_END
Definition: zlib.h:178
inflate_codes_statef * inflate_codes_new(uInt bl, uInt bd, inflate_huft *tl, inflate_huft *td, z_streamp z)
Definition: infcodes.c:58
Byte FAR Bytef
Definition: zconf.h:400
z_stream FAR * z_streamp
Definition: zlib.h:108
inflate_huft * dtree
Definition: infcodes.c:53
#define e
Definition: ke_i.h:82
void ZLIB_INTERNAL inflate_fast(z_streamp strm, unsigned start)
Definition: inffast.c:50
#define Z_OK
Definition: zlib.h:177
void inflate_codes_free(inflate_codes_statef *c, z_streamp z)
Definition: infcodes.c:244
GLdouble GLdouble z
Definition: glext.h:5874
Definition: infcodes.c:18
int inflate_codes(inflate_blocks_statef *s, z_streamp z, int r)
Definition: infcodes.c:80
#define b
Definition: ke_i.h:79
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
Definition: infcodes.c:25
#define Assert(cond, msg)
Definition: zutil.h:196
unsigned long uLong
Definition: zconf.h:394
#define Tracevv(x)
Definition: zutil.h:199
GLfloat f
Definition: glext.h:7540
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
const GLubyte * c
Definition: glext.h:8905
#define ZFREE(strm, addr)
Definition: zutil.h:212
inflate_huft * tree
Definition: infcodes.c:39
#define Z_DATA_ERROR
Definition: zlib.h:182
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
Definition: infcodes.c:23
GLdouble s
Definition: gl.h:2039
struct inflate_huft_s FAR inflate_huft
Definition: inftrees.h:17
static IHTMLWindow2 * window
Definition: events.c:77
#define local
Definition: zutil.h:30
Definition: infcodes.c:17
union inflate_codes_state::@3843 sub
#define Tracev(x)
Definition: zutil.h:198
#define f
Definition: ke_i.h:83
#define LOAD
Definition: infutil.h:85
#define OUTBYTE(a)
Definition: infutil.h:83
#define FLUSH
Definition: infutil.h:81
#define c
Definition: ke_i.h:80
FILE * stderr
#define DUMPBITS(j)
Definition: infutil.h:76
GLfloat GLfloat p
Definition: glext.h:8902
#define Z_NULL
Definition: zlib.h:212
const uInt inflate_mask[17]
Definition: infutil.c:14
int k
Definition: mpi.c:3369
unsigned int uInt
Definition: zconf.h:393
struct inflate_codes_state FAR inflate_codes_statef
Definition: infcodes.h:15