1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/compressionlibs/ziplib/test/oldezlib/Zlib/infcodes.c Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,249 @@
1.4 +/* infcodes.c -- process literals and length/distance pairs
1.5 + * Copyright (C) 1995-1998 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 + 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 + inflate_huft *ltree; /* literal/length/eob tree */
1.57 + inflate_huft *dtree; /* distance tree */
1.58 +
1.59 +};
1.60 +
1.61 +
1.62 +inflate_codes_statef *inflate_codes_new(uInt bl, uInt bd, inflate_huft *tl, inflate_huft *td, z_streamp z)
1.63 +/* inflate_huft *td need separate declaration for Borland C++ */
1.64 +{
1.65 + inflate_codes_statef *c;
1.66 +
1.67 + if ((c = (inflate_codes_statef *)
1.68 + ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL)
1.69 + {
1.70 + c->mode = START;
1.71 + c->lbits = (Byte)bl;
1.72 + c->dbits = (Byte)bd;
1.73 + c->ltree = tl;
1.74 + c->dtree = td;
1.75 + Tracev((stderr, "inflate: codes new\n"));
1.76 + }
1.77 + return c;
1.78 +}
1.79 +
1.80 +
1.81 +int inflate_codes(inflate_blocks_statef *s,z_streamp z, int r)
1.82 +{
1.83 + uInt j; /* temporary storage */
1.84 + inflate_huft *t; /* temporary pointer */
1.85 + uInt e; /* extra bits or operation */
1.86 + uLong b; /* bit buffer */
1.87 + uInt k; /* bits in bit buffer */
1.88 + Bytef *p; /* input data pointer */
1.89 + uInt n; /* bytes available there */
1.90 + Bytef *q; /* output window write pointer */
1.91 + uInt m; /* bytes to end of window or read pointer */
1.92 + Bytef *f; /* pointer to copy strings from */
1.93 + inflate_codes_statef *c = s->sub.decode.codes; /* codes state */
1.94 +
1.95 + /* copy input/output information to locals (UPDATE macro restores) */
1.96 + LOAD
1.97 +
1.98 + /* process input and output based on current state */
1.99 + while (1) switch (c->mode)
1.100 + { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
1.101 + case START: /* x: set up for LEN */
1.102 +#ifndef SLOW
1.103 + if (m >= 258 && n >= 10)
1.104 + {
1.105 + UPDATE
1.106 + r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);
1.107 + LOAD
1.108 + if (r != Z_OK)
1.109 + {
1.110 + c->mode = r == Z_STREAM_END ? WASH : BADCODE;
1.111 + break;
1.112 + }
1.113 + }
1.114 +#endif /* !SLOW */
1.115 + c->sub.code.need = c->lbits;
1.116 + c->sub.code.tree = c->ltree;
1.117 + c->mode = LEN;
1.118 + case LEN: /* i: get length/literal/eob next */
1.119 + j = c->sub.code.need;
1.120 + NEEDBITS(j)
1.121 + t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
1.122 + DUMPBITS(t->bits)
1.123 + e = (uInt)(t->exop);
1.124 + if (e == 0) /* literal */
1.125 + {
1.126 + c->sub.lit = t->base;
1.127 + Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
1.128 + "inflate: literal '%c'\n" :
1.129 + "inflate: literal 0x%02x\n", t->base));
1.130 + c->mode = LIT;
1.131 + break;
1.132 + }
1.133 + if (e & 16) /* length */
1.134 + {
1.135 + c->sub.copy.get = e & 15;
1.136 + c->len = t->base;
1.137 + c->mode = LENEXT;
1.138 + break;
1.139 + }
1.140 + if ((e & 64) == 0) /* next table */
1.141 + {
1.142 + c->sub.code.need = e;
1.143 + c->sub.code.tree = t + t->base;
1.144 + break;
1.145 + }
1.146 + if (e & 32) /* end of block */
1.147 + {
1.148 + Tracevv((stderr, "inflate: end of block\n"));
1.149 + c->mode = WASH;
1.150 + break;
1.151 + }
1.152 + c->mode = BADCODE; /* invalid code */
1.153 + z->msg = (char*)"invalid literal/length code";
1.154 + r = Z_DATA_ERROR;
1.155 + LEAVE
1.156 + case LENEXT: /* i: getting length extra (have base) */
1.157 + j = c->sub.copy.get;
1.158 + NEEDBITS(j)
1.159 + c->len += (uInt)b & inflate_mask[j];
1.160 + DUMPBITS(j)
1.161 + c->sub.code.need = c->dbits;
1.162 + c->sub.code.tree = c->dtree;
1.163 + Tracevv((stderr, "inflate: length %u\n", c->len));
1.164 + c->mode = DIST;
1.165 + case DIST: /* i: get distance next */
1.166 + j = c->sub.code.need;
1.167 + NEEDBITS(j)
1.168 + t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
1.169 + DUMPBITS(t->bits)
1.170 + e = (uInt)(t->exop);
1.171 + if (e & 16) /* distance */
1.172 + {
1.173 + c->sub.copy.get = e & 15;
1.174 + c->sub.copy.dist = t->base;
1.175 + c->mode = DISTEXT;
1.176 + break;
1.177 + }
1.178 + if ((e & 64) == 0) /* next table */
1.179 + {
1.180 + c->sub.code.need = e;
1.181 + c->sub.code.tree = t + t->base;
1.182 + break;
1.183 + }
1.184 + c->mode = BADCODE; /* invalid code */
1.185 + z->msg = (char*)"invalid distance code";
1.186 + r = Z_DATA_ERROR;
1.187 + LEAVE
1.188 + case DISTEXT: /* i: getting distance extra */
1.189 + j = c->sub.copy.get;
1.190 + NEEDBITS(j)
1.191 + c->sub.copy.dist += (uInt)b & inflate_mask[j];
1.192 + DUMPBITS(j)
1.193 + Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist));
1.194 + c->mode = COPY;
1.195 + case COPY: /* o: copying bytes in window, waiting for space */
1.196 +#ifndef __TURBOC__ /* Turbo C bug for following expression */
1.197 + f = (uInt)(q - s->window) < c->sub.copy.dist ?
1.198 + s->end - (c->sub.copy.dist - (q - s->window)) :
1.199 + q - c->sub.copy.dist;
1.200 +#else
1.201 + f = q - c->sub.copy.dist;
1.202 + if ((uInt)(q - s->window) < c->sub.copy.dist)
1.203 + f = s->end - (c->sub.copy.dist - (uInt)(q - s->window));
1.204 +#endif
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(inflate_codes_statef *c, z_streamp z)
1.249 +{
1.250 + ZFREE(z, c);
1.251 + Tracev((stderr, "inflate: codes free\n"));
1.252 +}