1/* infcodes.c -- process literals and length/distance pairs 2 * Copyright (C) 1995-1998 Mark Adler 3 * For conditions of distribution and use, see copyright notice in zlib.h 4 */ 5 6#include <linux/zutil.h> 7#include "inftrees.h" 8#include "infblock.h" 9#include "infcodes.h" 10#include "infutil.h" 11#include "inffast.h" 12 13/* simplify the use of the inflate_huft type with some defines */ 14#define exop word.what.Exop 15#define bits word.what.Bits 16 17inflate_codes_statef *zlib_inflate_codes_new(bl, bd, tl, td, z) 18uInt bl, bd; 19inflate_huft *tl; 20inflate_huft *td; /* need separate declaration for Borland C++ */ 21z_streamp z; 22{ 23 inflate_codes_statef *c; 24 25 c = &WS(z)->working_state; 26 { 27 c->mode = START; 28 c->lbits = (Byte)bl; 29 c->dbits = (Byte)bd; 30 c->ltree = tl; 31 c->dtree = td; 32 } 33 return c; 34} 35 36 37int zlib_inflate_codes(s, z, r) 38inflate_blocks_statef *s; 39z_streamp z; 40int r; 41{ 42 uInt j; /* temporary storage */ 43 inflate_huft *t; /* temporary pointer */ 44 uInt e; /* extra bits or operation */ 45 uLong b; /* bit buffer */ 46 uInt k; /* bits in bit buffer */ 47 Bytef *p; /* input data pointer */ 48 uInt n; /* bytes available there */ 49 Bytef *q; /* output window write pointer */ 50 uInt m; /* bytes to end of window or read pointer */ 51 Bytef *f; /* pointer to copy strings from */ 52 inflate_codes_statef *c = s->sub.decode.codes; /* codes state */ 53 54 /* copy input/output information to locals (UPDATE macro restores) */ 55 LOAD 56 57 /* process input and output based on current state */ 58 while (1) switch (c->mode) 59 { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ 60 case START: /* x: set up for LEN */ 61#ifndef SLOW 62 if (m >= 258 && n >= 10) 63 { 64 UPDATE 65 r = zlib_inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z); 66 LOAD 67 if (r != Z_OK) 68 { 69 c->mode = r == Z_STREAM_END ? WASH : BADCODE; 70 break; 71 } 72 } 73#endif /* !SLOW */ 74 c->sub.code.need = c->lbits; 75 c->sub.code.tree = c->ltree; 76 c->mode = LEN; 77 case LEN: /* i: get length/literal/eob next */ 78 j = c->sub.code.need; 79 NEEDBITS(j) 80 t = c->sub.code.tree + ((uInt)b & zlib_inflate_mask[j]); 81 DUMPBITS(t->bits) 82 e = (uInt)(t->exop); 83 if (e == 0) /* literal */ 84 { 85 c->sub.lit = t->base; 86 c->mode = LIT; 87 break; 88 } 89 if (e & 16) /* length */ 90 { 91 c->sub.copy.get = e & 15; 92 c->len = t->base; 93 c->mode = LENEXT; 94 break; 95 } 96 if ((e & 64) == 0) /* next table */ 97 { 98 c->sub.code.need = e; 99 c->sub.code.tree = t + t->base; 100 break; 101 } 102 if (e & 32) /* end of block */ 103 { 104 c->mode = WASH; 105 break; 106 } 107 c->mode = BADCODE; /* invalid code */ 108 z->msg = (char*)"invalid literal/length code"; 109 r = Z_DATA_ERROR; 110 LEAVE 111 case LENEXT: /* i: getting length extra (have base) */ 112 j = c->sub.copy.get; 113 NEEDBITS(j) 114 c->len += (uInt)b & zlib_inflate_mask[j]; 115 DUMPBITS(j) 116 c->sub.code.need = c->dbits; 117 c->sub.code.tree = c->dtree; 118 c->mode = DIST; 119 case DIST: /* i: get distance next */ 120 j = c->sub.code.need; 121 NEEDBITS(j) 122 t = c->sub.code.tree + ((uInt)b & zlib_inflate_mask[j]); 123 DUMPBITS(t->bits) 124 e = (uInt)(t->exop); 125 if (e & 16) /* distance */ 126 { 127 c->sub.copy.get = e & 15; 128 c->sub.copy.dist = t->base; 129 c->mode = DISTEXT; 130 break; 131 } 132 if ((e & 64) == 0) /* next table */ 133 { 134 c->sub.code.need = e; 135 c->sub.code.tree = t + t->base; 136 break; 137 } 138 c->mode = BADCODE; /* invalid code */ 139 z->msg = (char*)"invalid distance code"; 140 r = Z_DATA_ERROR; 141 LEAVE 142 case DISTEXT: /* i: getting distance extra */ 143 j = c->sub.copy.get; 144 NEEDBITS(j) 145 c->sub.copy.dist += (uInt)b & zlib_inflate_mask[j]; 146 DUMPBITS(j) 147 c->mode = COPY; 148 case COPY: /* o: copying bytes in window, waiting for space */ 149#ifndef __TURBOC__ /* Turbo C bug for following expression */ 150 f = (uInt)(q - s->window) < c->sub.copy.dist ? 151 s->end - (c->sub.copy.dist - (q - s->window)) : 152 q - c->sub.copy.dist; 153#else 154 f = q - c->sub.copy.dist; 155 if ((uInt)(q - s->window) < c->sub.copy.dist) 156 f = s->end - (c->sub.copy.dist - (uInt)(q - s->window)); 157#endif 158 while (c->len) 159 { 160 NEEDOUT 161 OUTBYTE(*f++) 162 if (f == s->end) 163 f = s->window; 164 c->len--; 165 } 166 c->mode = START; 167 break; 168 case LIT: /* o: got literal, waiting for output space */ 169 NEEDOUT 170 OUTBYTE(c->sub.lit) 171 c->mode = START; 172 break; 173 case WASH: /* o: got eob, possibly more output */ 174 if (k > 7) /* return unused byte, if any */ 175 { 176 k -= 8; 177 n++; 178 p--; /* can always return one */ 179 } 180 FLUSH 181 if (s->read != s->write) 182 LEAVE 183 c->mode = END; 184 case END: 185 r = Z_STREAM_END; 186 LEAVE 187 case BADCODE: /* x: got error */ 188 r = Z_DATA_ERROR; 189 LEAVE 190 default: 191 r = Z_STREAM_ERROR; 192 LEAVE 193 } 194#ifdef NEED_DUMMY_RETURN 195 return Z_STREAM_ERROR; /* Some dumb compilers complain without this */ 196#endif 197} 198 199 200void zlib_inflate_codes_free(c, z) 201inflate_codes_statef *c; 202z_streamp z; 203{ 204} 205