⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 liteunzip.c

📁 是一个C语言的压缩和解压缩的DLL源程序.
💻 C
📖 第 1 页 / 共 5 页
字号:
			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 + -