| 1023 | |
| 1024 | |
| 1025 | int inflate_codes(inflate_blocks_statef *s, z_streamp z, int r) |
| 1026 | { |
| 1027 | uInt j; // temporary storage |
| 1028 | const inflate_huft *t; // temporary pointer |
| 1029 | uInt e; // extra bits or operation |
| 1030 | uLong b; // bit buffer |
| 1031 | uInt k; // bits in bit buffer |
| 1032 | Byte *p; // input data pointer |
| 1033 | uInt n; // bytes available there |
| 1034 | Byte *q; // output window write pointer |
| 1035 | uInt m; // bytes to end of window or read pointer |
| 1036 | Byte *f; // pointer to copy strings from |
| 1037 | inflate_codes_statef *c = s->sub.decode.codes; // codes state |
| 1038 | |
| 1039 | // copy input/output information to locals (UPDATE macro restores) |
| 1040 | LOAD |
| 1041 | |
| 1042 | // process input and output based on current state |
| 1043 | for(;;) switch (c->mode) |
| 1044 | { // waiting for "i:"=input, "o:"=output, "x:"=nothing |
| 1045 | case START: // x: set up for LEN |
| 1046 | #ifndef SLOW |
| 1047 | if (m >= 258 && n >= 10) |
| 1048 | { |
| 1049 | UPDATE |
| 1050 | r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z); |
| 1051 | LOAD |
| 1052 | if (r != Z_OK) |
| 1053 | { |
| 1054 | c->mode = r == Z_STREAM_END ? WASH : BADCODE; |
| 1055 | break; |
| 1056 | } |
| 1057 | } |
| 1058 | #endif // !SLOW |
| 1059 | c->sub.code.need = c->lbits; |
| 1060 | c->sub.code.tree = c->ltree; |
| 1061 | c->mode = LEN; |
| 1062 | case LEN: // i: get length/literal/eob next |
| 1063 | j = c->sub.code.need; |
| 1064 | NEEDBITS(j) |
| 1065 | t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); |
| 1066 | DUMPBITS(t->bits) |
| 1067 | e = (uInt)(t->exop); |
| 1068 | if (e == 0) // literal |
| 1069 | { |
| 1070 | c->sub.lit = t->base; |
| 1071 | LuTracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? |
| 1072 | "inflate: literal '%c'\n" : |
| 1073 | "inflate: literal 0x%02x\n", t->base)); |
| 1074 | c->mode = LIT; |
| 1075 | break; |
| 1076 | } |
| 1077 | if (e & 16) // length |
| 1078 | { |
| 1079 | c->sub.copy.get = e & 15; |
| 1080 | c->len = t->base; |
| 1081 | c->mode = LENEXT; |
| 1082 | break; |