You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

infcodes.c 7.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  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. #include "zutil.h"
  6. #include "inftrees.h"
  7. #include "infblock.h"
  8. #include "infcodes.h"
  9. #include "infutil.h"
  10. #include "inffast.h"
  11. /* simplify the use of the inflate_huft type with some defines */
  12. #define exop word.what.Exop
  13. #define bits word.what.Bits
  14. typedef enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
  15. START, /* x: set up for LEN */
  16. LEN, /* i: get length/literal/eob next */
  17. LENEXT, /* i: getting length extra (have base) */
  18. DIST, /* i: get distance next */
  19. DISTEXT, /* i: getting distance extra */
  20. COPY, /* o: copying bytes in window, waiting for space */
  21. LIT, /* o: got literal, waiting for output space */
  22. WASH, /* o: got eob, possibly still output waiting */
  23. END, /* x: got eob and all data flushed */
  24. BADCODE} /* x: got error */
  25. inflate_codes_mode;
  26. /* inflate codes private state */
  27. struct inflate_codes_state {
  28. /* mode */
  29. inflate_codes_mode mode; /* current inflate_codes mode */
  30. /* mode dependent information */
  31. uInt len;
  32. union {
  33. struct {
  34. inflate_huft *tree; /* pointer into tree */
  35. uInt need; /* bits needed */
  36. } code; /* if LEN or DIST, where in tree */
  37. uInt lit; /* if LIT, literal */
  38. struct {
  39. uInt get; /* bits to get for extra */
  40. uInt dist; /* distance back to copy from */
  41. } copy; /* if EXT or COPY, where and how much */
  42. } sub; /* submode */
  43. /* mode independent information */
  44. Byte lbits; /* ltree bits decoded per branch */
  45. Byte dbits; /* dtree bits decoder per branch */
  46. inflate_huft *ltree; /* literal/length/eob tree */
  47. inflate_huft *dtree; /* distance tree */
  48. };
  49. inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z)
  50. uInt bl, bd;
  51. inflate_huft *tl;
  52. inflate_huft *td; /* need separate declaration for Borland C++ */
  53. z_streamp z;
  54. {
  55. inflate_codes_statef *c;
  56. if ((c = (inflate_codes_statef *)
  57. ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL)
  58. {
  59. c->mode = START;
  60. c->lbits = (Byte)bl;
  61. c->dbits = (Byte)bd;
  62. c->ltree = tl;
  63. c->dtree = td;
  64. Tracev((stderr, "inflate: codes new\n"));
  65. }
  66. return c;
  67. }
  68. int inflate_codes(s, z, r)
  69. inflate_blocks_statef *s;
  70. z_streamp z;
  71. int r;
  72. {
  73. uInt j; /* temporary storage */
  74. inflate_huft *t; /* temporary pointer */
  75. uInt e; /* extra bits or operation */
  76. uLong b; /* bit buffer */
  77. uInt k; /* bits in bit buffer */
  78. Bytef *p; /* input data pointer */
  79. uInt n; /* bytes available there */
  80. Bytef *q; /* output window write pointer */
  81. uInt m; /* bytes to end of window or read pointer */
  82. Bytef *f; /* pointer to copy strings from */
  83. inflate_codes_statef *c = s->sub.decode.codes; /* codes state */
  84. /* copy input/output information to locals (UPDATE macro restores) */
  85. LOAD
  86. /* process input and output based on current state */
  87. while (1) switch (c->mode)
  88. { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
  89. case START: /* x: set up for LEN */
  90. #ifndef SLOW
  91. if (m >= 258 && n >= 10)
  92. {
  93. UPDATE
  94. r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);
  95. LOAD
  96. if (r != Z_OK)
  97. {
  98. c->mode = r == Z_STREAM_END ? WASH : BADCODE;
  99. break;
  100. }
  101. }
  102. #endif /* !SLOW */
  103. c->sub.code.need = c->lbits;
  104. c->sub.code.tree = c->ltree;
  105. c->mode = LEN;
  106. case LEN: /* i: get length/literal/eob next */
  107. j = c->sub.code.need;
  108. NEEDBITS(j)
  109. t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
  110. DUMPBITS(t->bits)
  111. e = (uInt)(t->exop);
  112. if (e == 0) /* literal */
  113. {
  114. c->sub.lit = t->base;
  115. Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
  116. "inflate: literal '%c'\n" :
  117. "inflate: literal 0x%02x\n", t->base));
  118. c->mode = LIT;
  119. break;
  120. }
  121. if (e & 16) /* length */
  122. {
  123. c->sub.copy.get = e & 15;
  124. c->len = t->base;
  125. c->mode = LENEXT;
  126. break;
  127. }
  128. if ((e & 64) == 0) /* next table */
  129. {
  130. c->sub.code.need = e;
  131. c->sub.code.tree = t + t->base;
  132. break;
  133. }
  134. if (e & 32) /* end of block */
  135. {
  136. Tracevv((stderr, "inflate: end of block\n"));
  137. c->mode = WASH;
  138. break;
  139. }
  140. c->mode = BADCODE; /* invalid code */
  141. z->msg = (char*)"invalid literal/length code";
  142. r = Z_DATA_ERROR;
  143. LEAVE
  144. case LENEXT: /* i: getting length extra (have base) */
  145. j = c->sub.copy.get;
  146. NEEDBITS(j)
  147. c->len += (uInt)b & inflate_mask[j];
  148. DUMPBITS(j)
  149. c->sub.code.need = c->dbits;
  150. c->sub.code.tree = c->dtree;
  151. Tracevv((stderr, "inflate: length %u\n", c->len));
  152. c->mode = DIST;
  153. case DIST: /* i: get distance next */
  154. j = c->sub.code.need;
  155. NEEDBITS(j)
  156. t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
  157. DUMPBITS(t->bits)
  158. e = (uInt)(t->exop);
  159. if (e & 16) /* distance */
  160. {
  161. c->sub.copy.get = e & 15;
  162. c->sub.copy.dist = t->base;
  163. c->mode = DISTEXT;
  164. break;
  165. }
  166. if ((e & 64) == 0) /* next table */
  167. {
  168. c->sub.code.need = e;
  169. c->sub.code.tree = t + t->base;
  170. break;
  171. }
  172. c->mode = BADCODE; /* invalid code */
  173. z->msg = (char*)"invalid distance code";
  174. r = Z_DATA_ERROR;
  175. LEAVE
  176. case DISTEXT: /* i: getting distance extra */
  177. j = c->sub.copy.get;
  178. NEEDBITS(j)
  179. c->sub.copy.dist += (uInt)b & inflate_mask[j];
  180. DUMPBITS(j)
  181. Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist));
  182. c->mode = COPY;
  183. case COPY: /* o: copying bytes in window, waiting for space */
  184. f = q - c->sub.copy.dist;
  185. while (f < s->window) /* modulo window size-"while" instead */
  186. f += s->end - s->window; /* of "if" handles invalid distances */
  187. while (c->len)
  188. {
  189. NEEDOUT
  190. OUTBYTE(*f++)
  191. if (f == s->end)
  192. f = s->window;
  193. c->len--;
  194. }
  195. c->mode = START;
  196. break;
  197. case LIT: /* o: got literal, waiting for output space */
  198. NEEDOUT
  199. OUTBYTE(c->sub.lit)
  200. c->mode = START;
  201. break;
  202. case WASH: /* o: got eob, possibly more output */
  203. if (k > 7) /* return unused byte, if any */
  204. {
  205. Assert(k < 16, "inflate_codes grabbed too many bytes")
  206. k -= 8;
  207. n++;
  208. p--; /* can always return one */
  209. }
  210. FLUSH
  211. if (s->read != s->write)
  212. LEAVE
  213. c->mode = END;
  214. case END:
  215. r = Z_STREAM_END;
  216. LEAVE
  217. case BADCODE: /* x: got error */
  218. r = Z_DATA_ERROR;
  219. LEAVE
  220. default:
  221. r = Z_STREAM_ERROR;
  222. LEAVE
  223. }
  224. #ifdef NEED_DUMMY_RETURN
  225. return Z_STREAM_ERROR; /* Some dumb compilers complain without this */
  226. #endif
  227. }
  228. void inflate_codes_free(c, z)
  229. inflate_codes_statef *c;
  230. z_streamp z;
  231. {
  232. ZFREE(z, c);
  233. Tracev((stderr, "inflate: codes free\n"));
  234. }