Visualization Library 2.0.0-b5

A lightweight C++ OpenGL middleware for 2D/3D graphics

VL     Star     Watch     Fork     Issue

[Download] [Tutorials] [All Classes] [Grouped Classes]
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 */
30 struct inflate_codes_state {
31 
32  /* mode */
33  inflate_codes_mode mode; /* current inflate_codes mode */
34 
35  /* mode dependent information */
36  uInt len;
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 }
local int inflate_codes(inflate_blocks_statef *s, z_streamp z, int r)
Definition: infcodes.c:80
unsigned int uInt
Definition: zconf.h:221
#define Z_STREAM_ERROR
Definition: zlib.h:136
Definition: infcodes.c:24
GLfloat GLfloat p
struct inflate_blocks_state FAR inflate_blocks_statef
Definition: infblock.h:15
#define LEAVE
Definition: infutil.h:70
inflate_codes_mode
Definition: infcodes.c:16
#define ZALLOC(strm, items, size)
Definition: zutil.h:210
GLdouble GLdouble GLdouble GLdouble q
Definition: infcodes.c:22
Definition: infcodes.c:20
#define NEEDBITS(j)
Definition: infutil.h:75
#define NEEDOUT
Definition: infutil.h:82
#define UPDATE
Definition: infutil.h:69
void inflate_fast(z_streamp strm, unsigned start)
Definition: inffas86.c:71
GLboolean GLboolean GLboolean b
GLdouble GLdouble z
#define Z_OK
Definition: zlib.h:132
z_stream FAR * z_streamp
Definition: zlib.h:89
Definition: infcodes.c:18
GLenum GLsizei len
GLenum mode
unsigned long uLong
Definition: zconf.h:222
local void inflate_codes_free(inflate_codes_statef *c, z_streamp z)
Definition: infcodes.c:244
Definition: infcodes.c:25
#define Assert(cond, msg)
Definition: zutil.h:196
#define Tracevv(x)
Definition: zutil.h:199
GLdouble GLdouble GLdouble r
local const uInt inflate_mask[17]
Definition: infutil.c:14
#define Z_NULL
Definition: zlib.h:164
GLdouble n
#define ZFREE(strm, addr)
Definition: zutil.h:212
const GLubyte * c
const GLfloat * m
Definition: infcodes.c:23
struct inflate_huft_s FAR inflate_huft
Definition: inftrees.h:17
#define local
Definition: zutil.h:30
Definition: infcodes.c:17
#define Tracev(x)
Definition: zutil.h:198
Byte FAR Bytef
Definition: zconf.h:228
GLdouble s
#define LOAD
Definition: infutil.h:85
#define OUTBYTE(a)
Definition: infutil.h:83
unsigned char Byte
Definition: zconf.h:219
#define FLUSH
Definition: infutil.h:81
local inflate_codes_statef * inflate_codes_new(uInt bl, uInt bd, inflate_huft *tl, inflate_huft *td, z_streamp z)
Definition: infcodes.c:58
#define DUMPBITS(j)
Definition: infutil.h:76
GLdouble GLdouble t
local int * code
Definition: enough.c:174
#define Z_DATA_ERROR
Definition: zlib.h:137
GLfloat f
struct inflate_codes_state FAR inflate_codes_statef
Definition: infcodes.h:15
#define Z_STREAM_END
Definition: zlib.h:133