📄 liteunzip.c
字号:
c->sub.code.need = c->lbits;
c->sub.code.tree = c->ltree;
c->mode = LEN;
case LEN: // i: get length/literal/eob next
j = c->sub.code.need;
NEEDBITS(j)
t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
DUMPBITS(t->word.what.Bits)
e = (uInt)(t->word.what.Exop);
if (e == 0) // literal
{
c->sub.lit = t->base;
#ifndef NDEBUG
LuTracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? "inflate: literal '%c'\n" : "inflate: literal 0x%02x\n", t->base));
#endif
c->mode = LIT;
break;
}
if (e & 16) // length
{
c->sub.copy.get = e & 15;
c->len = t->base;
c->mode = LENEXT;
break;
}
if ((e & 64) == 0) // next table
{
c->sub.code.need = e;
c->sub.code.tree = t + t->base;
break;
}
if (e & 32) // end of block
{
#ifndef NDEBUG
LuTracevv((stderr, "inflate: end of block\n"));
#endif
c->mode = WASH;
break;
}
c->mode = BADCODE; // invalid code
#ifndef NDEBUG
z->msg = (char*)"invalid literal/length code";
#endif
r = Z_DATA_ERROR;
LEAVE
case LENEXT: // i: getting length extra (have base)
j = c->sub.copy.get;
NEEDBITS(j)
c->len += (uInt)b & inflate_mask[j];
DUMPBITS(j)
c->sub.code.need = c->dbits;
c->sub.code.tree = c->dtree;
#ifndef NDEBUG
LuTracevv((stderr, "inflate: length %u\n", c->len));
#endif
c->mode = DIST;
case DIST: // i: get distance next
j = c->sub.code.need;
NEEDBITS(j)
t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
DUMPBITS(t->word.what.Bits)
e = (uInt)(t->word.what.Exop);
if (e & 16) // distance
{
c->sub.copy.get = e & 15;
c->sub.copy.dist = t->base;
c->mode = DISTEXT;
break;
}
if ((e & 64) == 0) // next table
{
c->sub.code.need = e;
c->sub.code.tree = t + t->base;
break;
}
c->mode = BADCODE; // invalid code
#ifndef NDEBUG
z->msg = (char*)"invalid distance code";
#endif
r = Z_DATA_ERROR;
LEAVE
case DISTEXT: // i: getting distance extra
j = c->sub.copy.get;
NEEDBITS(j)
c->sub.copy.dist += (uInt)b & inflate_mask[j];
DUMPBITS(j)
#ifndef NDEBUG
LuTracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist));
#endif
c->mode = COPY;
case COPY: // o: copying bytes in window, waiting for space
f = q - c->sub.copy.dist; while (f < s->window) // modulo window size-"while" instead f += s->end - s->window; // of "if" handles invalid distances
while (c->len) {
NEEDOUT
OUTBYTE(*f++)
if (f == s->end) f = s->window;
--c->len;
}
c->mode = START;
break;
case LIT: // o: got literal, waiting for output space
NEEDOUT
OUTBYTE(c->sub.lit)
c->mode = START;
break;
case WASH: // o: got eob, possibly more output
if (k > 7) // return unused byte, if any
{
k -= 8;
++n;
--p; // can always return one
}
FLUSH
if (s->read != s->write)
LEAVE
c->mode = END;
case END:
r = Z_STREAM_END;
LEAVE
case BADCODE: // x: got error
r = Z_DATA_ERROR;
LEAVE
default:
r = Z_STREAM_ERROR;
LEAVE
}
}
// infblock.c -- interpret and process block types to last block
// Copyright (C) 1995-1998 Mark Adler
// For conditions of distribution and use, see copyright notice in zlib.h
// Notes beyond the 1.93a appnote.txt:
//
// 1. Distance pointers never point before the beginning of the output stream.
// 2. Distance pointers can point back across blocks, up to 32k away.
// 3. There is an implied maximum of 7 bits for the bit length table and
// 15 bits for the actual data.
// 4. If only one code exists, then it is encoded using one bit. (Zero
// would be more efficient, but perhaps a little confusing.) If two
// codes exist, they are coded using one bit each (0 and 1).
// 5. There is no way of sending zero distance codes--a dummy must be
// sent if there are none. (History: a pre 2.0 version of PKZIP would
// store blocks with no distance codes, but this was discovered to be
// too harsh a criterion.) Valid only for 1.93a. 2.04c does allow
// zero distance codes, which is sent as one code of zero bits in
// length.
// 6. There are up to 286 literal/length codes. Code 256 represents the
// end-of-block. Note however that the static length tree defines
// 288 codes just to fill out the Huffman codes. Codes 286 and 287
// cannot be used though, since there is no length base or extra bits
// defined for them. Similarily, there are up to 30 distance codes.
// However, static trees define 32 codes (all 5 bits) to fill out the
// Huffman codes, but the last two had better not show up in the data.
// 7. Unzip can check dynamic Huffman blocks for complete code sets.
// The exception is that a single code would not be complete (see #4).
// 8. The five bits following the block type is really the number of
// literal codes sent minus 257.
// 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits
// (1+6+6). Therefore, to output three times the length, you output
// three codes (1+1+1), whereas to output four times the same length,
// you only need two codes (1+3). Hmm.
//10. In the tree reconstruction algorithm, Code = Code + Increment
// only if BitLength(i) is not zero. (Pretty obvious.)
//11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19)
//12. Note: length code 284 can represent 227-258, but length code 285
// really is 258. The last length deserves its own, short code
// since it gets used a lot in very redundant files. The length
// 258 is special since 258 - 3 (the min match length) is 255.
//13. The literal/length and distance code bit lengths are read as a
// single stream of lengths. It is possible (and advantageous) for
// a repeat code (16, 17, or 18) to go across the boundary between
// the two sets of lengths.
static void inflate_blocks_reset(Z_STREAM *z)
{
register INFLATE_BLOCKS_STATE *s;
s = &z->state->blocks;
z->state->sub.check.was = s->check;
if (s->mode == IBM_BTREE || s->mode == IBM_DTREE) GlobalFree(s->sub.trees.blens);
if (s->mode == IBM_CODES) GlobalFree(s->sub.decode.codes);
s->mode = IBM_TYPE;
s->bitk = s->bitb = 0;
s->read = s->write = s->window;
// if (!z->state->nowrap) z->adler = s->check = adler32(0, 0, 0);
#ifndef NDEBUG
LuTracev((stderr, "inflate: blocks reset\n"));
#endif
}
static int inflate_blocks(Z_STREAM * z, int r)
{
uInt t; // temporary storage
ULG b; // bit buffer
uInt k; // bits in bit buffer
UCH *p; // input data pointer
uInt n; // bytes available there
UCH *q; // output window write pointer
uInt m; // bytes to end of window or read pointer
register INFLATE_BLOCKS_STATE *s;
s = &z->state->blocks;
// copy input/output information to locals (UPDATE macro restores)
LOAD
// process input based on current state
for(;;)
{
switch (s->mode)
{
case IBM_TYPE:
{
NEEDBITS(3)
t = (uInt)b & 7;
s->last = t & 1;
switch (t >> 1)
{
// Stored
case 0:
{
#ifndef NDEBUG
LuTracev((stderr, "inflate: stored block%s\n", s->last ? " (last)" : ""));
#endif
DUMPBITS(3)
t = k & 7; // go to byte boundary
DUMPBITS(t)
s->mode = IBM_LENS; // get length of stored block
break;
}
// Fixes
case 1:
{
uInt bl, bd;
const INFLATE_HUFT *tl, *td;
#ifndef NDEBUG
LuTracev((stderr, "inflate: fixed codes block%s\n", s->last ? " (last)" : ""));
#endif
bl = Fixed_bl;
bd = Fixed_bd;
tl = Fixed_tl;
td = Fixed_td;
s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z);
if (s->sub.decode.codes == 0)
{
r = Z_MEM_ERROR;
LEAVE
}
DUMPBITS(3)
s->mode = IBM_CODES;
break;
}
// Dynamic
case 2:
{
#ifndef NDEBUG
LuTracev((stderr, "inflate: dynamic codes block%s\n", s->last ? " (last)" : ""));
#endif
DUMPBITS(3)
s->mode = IBM_TABLE;
break;
}
// Illegal
case 3:
{
DUMPBITS(3)
s->mode = IBM_BAD;
#ifndef NDEBUG
z->msg = (char*)"invalid block type";
#endif
r = Z_DATA_ERROR;
LEAVE
}
}
break;
}
case IBM_LENS:
{
NEEDBITS(32)
if ((((~b) >> 16) & 0xffff) != (b & 0xffff))
{
s->mode = IBM_BAD;
#ifndef NDEBUG
z->msg = (char*)"invalid stored block lengths";
#endif
r = Z_DATA_ERROR;
LEAVE
}
s->sub.left = (uInt)b & 0xffff;
b = k = 0; // dump bits
#ifndef NDEBUG
LuTracev((stderr, "inflate: stored length %u\n", s->sub.left));
#endif
s->mode = s->sub.left ? IBM_STORED : (s->last ? IBM_DRY : IBM_TYPE);
break;
}
case IBM_STORED:
{
if (n == 0)
LEAVE
NEEDOUT
t = s->sub.left;
if (t > n) t = n;
if (t > m) t = m;
CopyMemory(q, p, t);
p += t; n -= t;
q += t; m -= t;
if ((s->sub.left -= t) != 0)
break;
#ifndef NDEBUG
LuTracev((stderr, "inflate: stored end, %lu total out\n", z->total_out + (q >= s->read ? q - s->read : (s->end - s->read) + (q - s->window))));
#endif
s->mode = s->last ? IBM_DRY : IBM_TYPE;
break;
}
case IBM_TABLE:
{
NEEDBITS(14)
s->sub.trees.table = t = (uInt)b & 0x3fff;
// remove this section to workaround bug in pkzip
if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
{
s->mode = IBM_BAD;
#ifndef NDEBUG
z->msg = (char*)"too many length or distance symbols";
#endif
r = Z_DATA_ERROR;
LEAVE
}
// end remove
t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
if (!(s->sub.trees.blens = (uInt *)GlobalAlloc(GMEM_FIXED, t * sizeof(uInt))))
{
r = Z_MEM_ERROR;
LEAVE
}
DUMPBITS(14)
s->sub.trees.index = 0;
#ifndef NDEBUG
LuTracev((stderr, "inflate: table sizes ok\n"));
#endif
s->mode = IBM_BTREE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -