1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/compressionlibs/ziplib/test/oldezlib/EZLib/infcodes.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,251 @@
1.4 +/* infcodes.c -- process literals and length/distance pairs
1.5 + * Copyright (C) 1995-2002 Mark Adler
1.6 + * For conditions of distribution and use, see copyright notice in zlib.h
1.7 + */
1.8 +
1.9 +#include "zutil.h"
1.10 +#include "inftrees.h"
1.11 +#include "infblock.h"
1.12 +#include "infcodes.h"
1.13 +#include "infutil.h"
1.14 +#include "inffast.h"
1.15 +
1.16 +/* simplify the use of the inflate_huft type with some defines */
1.17 +#define exop word.what.Exop
1.18 +#define bits word.what.Bits
1.19 +
1.20 +typedef enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
1.21 + START, /* x: set up for LEN */
1.22 + LEN, /* i: get length/literal/eob next */
1.23 + LENEXT, /* i: getting length extra (have base) */
1.24 + DIST, /* i: get distance next */
1.25 + DISTEXT, /* i: getting distance extra */
1.26 + COPY, /* o: copying bytes in window, waiting for space */
1.27 + LIT, /* o: got literal, waiting for output space */
1.28 + WASH, /* o: got eob, possibly still output waiting */
1.29 + END, /* x: got eob and all data flushed */
1.30 + BADCODE} /* x: got error */
1.31 +inflate_codes_mode;
1.32 +
1.33 +/* inflate codes private state */
1.34 +struct inflate_codes_state {
1.35 +
1.36 + /* mode */
1.37 + inflate_codes_mode mode; /* current inflate_codes mode */
1.38 +
1.39 + /* mode dependent information */
1.40 + uInt len;
1.41 + union {
1.42 + struct {
1.43 + const inflate_huft *tree; /* pointer into tree */
1.44 + uInt need; /* bits needed */
1.45 + } code; /* if LEN or DIST, where in tree */
1.46 + uInt lit; /* if LIT, literal */
1.47 + struct {
1.48 + uInt get; /* bits to get for extra */
1.49 + uInt dist; /* distance back to copy from */
1.50 + } copy; /* if EXT or COPY, where and how much */
1.51 + } sub; /* submode */
1.52 +
1.53 + /* mode independent information */
1.54 + Byte lbits; /* ltree bits decoded per branch */
1.55 + Byte dbits; /* dtree bits decoder per branch */
1.56 + const inflate_huft *ltree; /* literal/length/eob tree */
1.57 + const inflate_huft *dtree; /* distance tree */
1.58 +
1.59 +};
1.60 +
1.61 +
1.62 +inflate_codes_statef *inflate_codes_new(
1.63 +uInt bl, uInt bd,
1.64 +const inflate_huft *tl,
1.65 +const inflate_huft *td, /* need separate declaration for Borland C++ */
1.66 +z_streamp z)
1.67 +{
1.68 + inflate_codes_statef *c;
1.69 +
1.70 + if ((c = (inflate_codes_statef *)
1.71 + ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL)
1.72 + {
1.73 + c->mode = START;
1.74 + c->lbits = (Byte)bl;
1.75 + c->dbits = (Byte)bd;
1.76 + c->ltree = tl;
1.77 + c->dtree = td;
1.78 + Tracev((stderr, "inflate: codes new\n"));
1.79 + }
1.80 + return c;
1.81 +}
1.82 +
1.83 +
1.84 +int inflate_codes(
1.85 +inflate_blocks_statef *s,
1.86 +z_streamp z,
1.87 +int r)
1.88 +{
1.89 + uInt j; /* temporary storage */
1.90 + const inflate_huft *t; /* temporary pointer */
1.91 + uInt e; /* extra bits or operation */
1.92 + uLong b; /* bit buffer */
1.93 + uInt k; /* bits in bit buffer */
1.94 + Bytef *p; /* input data pointer */
1.95 + uInt n; /* bytes available there */
1.96 + Bytef *q; /* output window write pointer */
1.97 + uInt m; /* bytes to end of window or read pointer */
1.98 + Bytef *f; /* pointer to copy strings from */
1.99 + inflate_codes_statef *c = s->sub.decode.codes; /* codes state */
1.100 +
1.101 + /* copy input/output information to locals (UPDATE macro restores) */
1.102 + LOAD
1.103 +
1.104 + /* process input and output based on current state */
1.105 + for (;;) switch (c->mode)
1.106 + { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
1.107 + case START: /* x: set up for LEN */
1.108 +#ifndef SLOW
1.109 + if (m >= 258 && n >= 10)
1.110 + {
1.111 + UPDATE
1.112 + r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);
1.113 + LOAD
1.114 + if (r != Z_OK)
1.115 + {
1.116 + c->mode = r == Z_STREAM_END ? WASH : BADCODE;
1.117 + break;
1.118 + }
1.119 + }
1.120 +#endif /* !SLOW */
1.121 + c->sub.code.need = c->lbits;
1.122 + c->sub.code.tree = c->ltree;
1.123 + c->mode = LEN;
1.124 + case LEN: /* i: get length/literal/eob next */
1.125 + j = c->sub.code.need;
1.126 + NEEDBITS(j)
1.127 + t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
1.128 + DUMPBITS(t->bits)
1.129 + e = (uInt)(t->exop);
1.130 + if (e == 0) /* literal */
1.131 + {
1.132 + c->sub.lit = t->base;
1.133 + Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
1.134 + "inflate: literal '%c'\n" :
1.135 + "inflate: literal 0x%02x\n", t->base));
1.136 + c->mode = LIT;
1.137 + break;
1.138 + }
1.139 + if (e & 16) /* length */
1.140 + {
1.141 + c->sub.copy.get = e & 15;
1.142 + c->len = t->base;
1.143 + c->mode = LENEXT;
1.144 + break;
1.145 + }
1.146 + if ((e & 64) == 0) /* next table */
1.147 + {
1.148 + c->sub.code.need = e;
1.149 + c->sub.code.tree = t + t->base;
1.150 + break;
1.151 + }
1.152 + if (e & 32) /* end of block */
1.153 + {
1.154 + Tracevv((stderr, "inflate: end of block\n"));
1.155 + c->mode = WASH;
1.156 + break;
1.157 + }
1.158 + c->mode = BADCODE; /* invalid code */
1.159 + z->msg = (char*)"invalid literal/length code";
1.160 + r = Z_DATA_ERROR;
1.161 + LEAVE
1.162 + case LENEXT: /* i: getting length extra (have base) */
1.163 + j = c->sub.copy.get;
1.164 + NEEDBITS(j)
1.165 + c->len += (uInt)b & inflate_mask[j];
1.166 + DUMPBITS(j)
1.167 + c->sub.code.need = c->dbits;
1.168 + c->sub.code.tree = c->dtree;
1.169 + Tracevv((stderr, "inflate: length %u\n", c->len));
1.170 + c->mode = DIST;
1.171 + case DIST: /* i: get distance next */
1.172 + j = c->sub.code.need;
1.173 + NEEDBITS(j)
1.174 + t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
1.175 + DUMPBITS(t->bits)
1.176 + e = (uInt)(t->exop);
1.177 + if (e & 16) /* distance */
1.178 + {
1.179 + c->sub.copy.get = e & 15;
1.180 + c->sub.copy.dist = t->base;
1.181 + c->mode = DISTEXT;
1.182 + break;
1.183 + }
1.184 + if ((e & 64) == 0) /* next table */
1.185 + {
1.186 + c->sub.code.need = e;
1.187 + c->sub.code.tree = t + t->base;
1.188 + break;
1.189 + }
1.190 + c->mode = BADCODE; /* invalid code */
1.191 + z->msg = (char*)"invalid distance code";
1.192 + r = Z_DATA_ERROR;
1.193 + LEAVE
1.194 + case DISTEXT: /* i: getting distance extra */
1.195 + j = c->sub.copy.get;
1.196 + NEEDBITS(j)
1.197 + c->sub.copy.dist += (uInt)b & inflate_mask[j];
1.198 + DUMPBITS(j)
1.199 + Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist));
1.200 + c->mode = COPY;
1.201 + case COPY: /* o: copying bytes in window, waiting for space */
1.202 + f = q - c->sub.copy.dist;
1.203 + while (f < s->window) /* modulo window size-"while" instead */
1.204 + f += s->end - s->window; /* of "if" handles invalid distances */
1.205 + while (c->len)
1.206 + {
1.207 + NEEDOUT
1.208 + OUTBYTE(*f++)
1.209 + if (f == s->end)
1.210 + f = s->window;
1.211 + c->len--;
1.212 + }
1.213 + c->mode = START;
1.214 + break;
1.215 + case LIT: /* o: got literal, waiting for output space */
1.216 + NEEDOUT
1.217 + OUTBYTE(c->sub.lit)
1.218 + c->mode = START;
1.219 + break;
1.220 + case WASH: /* o: got eob, possibly more output */
1.221 + if (k > 7) /* return unused byte, if any */
1.222 + {
1.223 + Assert(k < 16, "inflate_codes grabbed too many bytes")
1.224 + k -= 8;
1.225 + n++;
1.226 + p--; /* can always return one */
1.227 + }
1.228 + FLUSH
1.229 + if (s->read != s->write)
1.230 + LEAVE
1.231 + c->mode = END;
1.232 + case END:
1.233 + r = Z_STREAM_END;
1.234 + LEAVE
1.235 + case BADCODE: /* x: got error */
1.236 + r = Z_DATA_ERROR;
1.237 + LEAVE
1.238 + default:
1.239 + r = Z_STREAM_ERROR;
1.240 + LEAVE
1.241 + }
1.242 +#ifdef NEED_DUMMY_RETURN
1.243 + return Z_STREAM_ERROR; /* Some dumb compilers complain without this */
1.244 +#endif
1.245 +}
1.246 +
1.247 +
1.248 +void inflate_codes_free(
1.249 +inflate_codes_statef *c,
1.250 +z_streamp z)
1.251 +{
1.252 + ZFREE(z, c);
1.253 + Tracev((stderr, "inflate: codes free\n"));
1.254 +}