ReactOS 0.4.15-dev-8219-ge8b88cf
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
16typedef 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
59uInt bl, uInt bd,
60inflate_huft *tl,
61inflate_huft *td, /* need separate declaration for Borland C++ */
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
80local int inflate_codes( /* s, z, r) */
83int 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:
236 LEAVE
237 }
238#ifdef NEED_DUMMY_RETURN
239 return Z_STREAM_ERROR; /* Some dumb compilers complain without this */
240#endif
241}
242
243
244local void inflate_codes_free( /* c, z) */
246z_streamp z )
247{
248 ZFREE(z, c);
249 Tracev((stderr, "inflate: codes free\n"));
250}
#define LEAVE
Definition: classpnp.h:115
#define LOAD()
Definition: inflate.c:1111
#define ZALLOC(strm, items, size)
Definition: inflate.c:49
static void inflate_fast(z_streamp strm, unsigned start)
Definition: inflate.c:274
#define Assert(cond, msg)
Definition: inflate.c:41
#define UPDATE(check, buf, len)
Definition: inflate.c:1085
#define Tracev(x)
Definition: inflate.c:43
#define ZFREE(strm, addr)
Definition: inflate.c:51
#define NEEDBITS(n)
Definition: inflate.c:1151
#define Tracevv(x)
Definition: inflate.c:44
unsigned long uLong
Definition: zlib.h:39
z_stream FAR * z_streamp
Definition: zlib.h:80
#define Z_STREAM_END
Definition: zlib.h:115
unsigned int uInt
Definition: zlib.h:38
#define Z_OK
Definition: zlib.h:114
#define Z_DATA_ERROR
Definition: zlib.h:119
#define Z_STREAM_ERROR
Definition: zlib.h:118
#define Z_NULL
Definition: zlib.h:149
unsigned char Byte
Definition: zlib.h:37
Byte FAR Bytef
Definition: zlib.h:41
struct inflate_huft_s FAR inflate_huft
Definition: inftrees.h:17
#define local
Definition: zutil.h:30
GLdouble s
Definition: gl.h:2039
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLdouble GLdouble t
Definition: gl.h:2047
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
GLdouble n
Definition: glext.h:7729
const GLubyte * c
Definition: glext.h:8905
GLfloat f
Definition: glext.h:7540
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLfloat GLfloat p
Definition: glext.h:8902
GLdouble GLdouble z
Definition: glext.h:5874
const GLfloat * m
Definition: glext.h:10848
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
#define stderr
Definition: stdio.h:100
struct inflate_blocks_state FAR inflate_blocks_statef
Definition: infblock.h:15
void inflate_codes_free(inflate_codes_statef *c, z_streamp z)
Definition: infcodes.c:244
inflate_codes_statef * inflate_codes_new(uInt bl, uInt bd, inflate_huft *tl, inflate_huft *td, z_streamp z)
Definition: infcodes.c:58
inflate_codes_mode
Definition: infcodes.c:16
@ BADCODE
Definition: infcodes.c:26
@ START
Definition: infcodes.c:17
@ WASH
Definition: infcodes.c:24
@ LIT
Definition: infcodes.c:23
@ COPY
Definition: infcodes.c:22
@ DIST
Definition: infcodes.c:20
@ LENEXT
Definition: infcodes.c:19
@ END
Definition: infcodes.c:25
@ DISTEXT
Definition: infcodes.c:21
@ LEN
Definition: infcodes.c:18
int inflate_codes(inflate_blocks_statef *s, z_streamp z, int r)
Definition: infcodes.c:80
struct inflate_codes_state FAR inflate_codes_statef
Definition: infcodes.h:15
const uInt inflate_mask[17]
Definition: infutil.c:14
#define FLUSH
Definition: infutil.h:81
#define NEEDOUT
Definition: infutil.h:82
#define DUMPBITS(j)
Definition: infutil.h:76
#define OUTBYTE(a)
Definition: infutil.h:83
#define e
Definition: ke_i.h:82
#define f
Definition: ke_i.h:83
#define c
Definition: ke_i.h:80
#define b
Definition: ke_i.h:79
static IHTMLWindow2 * window
Definition: events.c:77
int k
Definition: mpi.c:3369
struct inflate_codes_state::@4250::@4251 code
union inflate_codes_state::@4250 sub
struct inflate_codes_state::@4250::@4252 copy
inflate_codes_mode mode
Definition: infcodes.c:33
inflate_huft * tree
Definition: infcodes.c:39
inflate_huft * ltree
Definition: infcodes.c:52
inflate_huft * dtree
Definition: infcodes.c:53