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

📄 complib.cpp

📁 一个解压程序,只要设定了解压路径和解压文件的种类,就可以随意解压
💻 CPP
字号:

#include "stdafx.h"
#include "complib.h"

/*** de-compress(lzw) ***/

#define BITS 16
#define INIT_BITS 9
#define BIT_MASK 0x1f
#define BLOCK_MODE 0x80
#define FIRST 257
#define CLEAR 256
static bool lzw_readonce(LZWDEC* lzw);

LZWDEC* lzw_start( int bits,bool blockmode,lzw_in proc,unsigned long param )
{
	LZWDEC* lzw = new LZWDEC;
	lzw->m_pGet = proc;
	lzw->m_Param= param;

	lzw->m_insize = lzw->m_rsize = (*lzw->m_pGet)(lzw->m_inbuf,ZBUFSIZ,lzw->m_Param);

	lzw->m_maxbits = bits;
	lzw->m_block_mode = blockmode;
	if( lzw->m_maxbits>BITS ){lzw_end(lzw);return NULL;}

	lzw->m_eof = false;
	lzw->m_n_bits = INIT_BITS;
	lzw->m_maxcode = (1<<lzw->m_n_bits) - 1;
	lzw->m_oldcode = -1;
	lzw->m_finchar = 0;
	lzw->m_posbits = 0;
	lzw->m_free_ent = lzw->m_block_mode ? FIRST : 256;
	memset(lzw->m_codetab, 0, 256);
	for(int code=0; code!=256; code++)
		lzw->m_htab[code]= code;
	return lzw;
}

int lzw_read( void *buf,int size,LZWDEC* lzw )
{
	int nread = 0;
	while( !lzw->m_eof && size>0 )
	{
		int in_avail;
		in_avail = lzw->m_strstream.Len();
		if( in_avail==0 )
		{
			if( !lzw_readonce(lzw) )
				break;
		}
		in_avail = lzw->m_strstream.Len();
		int n = in_avail>size?size:in_avail;
		lzw->m_strstream.Get( buf,n );
		nread += n;
		size -= n;
		buf = (void*)( (char*)buf+n );
	}
	return nread;
}

static bool lzw_readonce(LZWDEC* lzw)
{
resetbuf:
	lzw->m_insize -= lzw->m_posbits/8;
	memmove( lzw->m_inbuf,lzw->m_inbuf+lzw->m_posbits/8,lzw->m_insize );
	lzw->m_posbits = 0;

	if( lzw->m_insize<sizeof(lzw->m_inbuf)-ZBUFSIZ )
	{
		lzw->m_rsize = (*lzw->m_pGet)( lzw->m_inbuf+lzw->m_insize,ZBUFSIZ,lzw->m_Param );
		lzw->m_insize += lzw->m_rsize;
	}
	int inbits;
	if(lzw->m_rsize>0)
		inbits = (lzw->m_insize-lzw->m_insize%lzw->m_n_bits)*8;
	else
		inbits = (lzw->m_insize*8)-(lzw->m_n_bits-1);

	while( inbits>lzw->m_posbits )
	{
		if(lzw->m_free_ent > lzw->m_maxcode)
		{
			lzw->m_posbits = (lzw->m_posbits-1)+((lzw->m_n_bits*8)-(lzw->m_posbits-1+(lzw->m_n_bits*8))%(lzw->m_n_bits*8));
			lzw->m_n_bits++;
			if(lzw->m_n_bits == lzw->m_maxbits)
				lzw->m_maxcode = 1 << lzw->m_maxbits;
			else
				lzw->m_maxcode = (1 << lzw->m_n_bits) - 1;
			goto resetbuf;
		}

		int code;
		{
			int bitmask = (1<<lzw->m_n_bits) - 1;
			code = (*(long*)(&lzw->m_inbuf[lzw->m_posbits/8]) >> (lzw->m_posbits&7)) & bitmask;
			lzw->m_posbits += lzw->m_n_bits;
		}

		if( lzw->m_oldcode==-1 )
		{
			lzw->m_strstream.Putc((unsigned char)code);
			lzw->m_oldcode = code;
			lzw->m_finchar = (int) code;
			continue;
		}
		if( code==CLEAR && lzw->m_block_mode )
		{
			memset(lzw->m_codetab, 0, 256);
			lzw->m_free_ent = FIRST - 1;
			int tmp = (lzw->m_posbits-1) + (lzw->m_n_bits*8);
			lzw->m_posbits = tmp - tmp%(lzw->m_n_bits*8);
			lzw->m_n_bits = INIT_BITS;
			lzw->m_maxcode = (1 << lzw->m_n_bits) - 1;
			goto resetbuf;
		}
		int incode = code;
		unsigned char *stackp = lzw->m_htab + sizeof(lzw->m_htab);
		if( code>lzw->m_free_ent )
			return false;
		else if( code==lzw->m_free_ent )
		{
			* --stackp = (unsigned char)lzw->m_finchar;
			code = lzw->m_oldcode;
		}
		while( (unsigned int)code>=(unsigned)256 )
		{
			*--stackp	= lzw->m_htab[code];
			code		= lzw->m_codetab[code];
		}
		* --stackp = (unsigned char)(lzw->m_finchar = lzw->m_htab[code] );

		lzw->m_strstream.Put( (char*)stackp, lzw->m_htab + sizeof(lzw->m_htab) - stackp);
		if( lzw->m_free_ent < (1<<lzw->m_maxbits) )
		{
			lzw->m_codetab[lzw->m_free_ent]	= (unsigned short)lzw->m_oldcode;
			lzw->m_htab[lzw->m_free_ent]		= lzw->m_finchar;
			lzw->m_free_ent ++;
		}
		lzw->m_oldcode = incode;
	}

	if( lzw->m_rsize<=0 )
		lzw->m_eof=true;
	return true;
}

static int Z_in(void* buf,int size,unsigned long param)
{
	ZFILE* fp=(ZFILE*)param;
	size=fread(buf,1,size,fp->m_pFile);
	return size==-1 ? 0 : size;
}

ZFILE* Z_open(const char* name,const char* mode)
{
	ZFILE* fp = new ZFILE;
	fp->m_pFile = fopen(name,"rb");
	if( fp->m_pFile==NULL ){delete fp;return NULL;}

	unsigned char tmp[3];
	if( 3!=fread(tmp,1,3,fp->m_pFile) )
	{Z_close(fp);return NULL;}
	if( tmp[0]!=0x1f || tmp[1]!=0x9d ){Z_close(fp);return NULL;}

	fp->lzw=lzw_start( tmp[2]&BIT_MASK, (tmp[2]&BLOCK_MODE)!=0, Z_in, (unsigned long)fp );
	if( fp->lzw==NULL ){Z_close(fp);return NULL;}
	return fp;
}

int Z_close(ZFILE* fp)
{
	if( fp==NULL )
		return EOF;
	lzw_end( fp->lzw );
	fclose( fp->m_pFile );
	delete fp;
	return 0;
}

int Z_read( void *buf,int size,ZFILE* fp )
{
	return lzw_read(buf,size,fp->lzw);
}

/*** de-pack ***/

#define MIN(a,b) ( (a)<=(b)?(a):(b) )
#define look_bits(code,bits,mask) \
{ \
  while (fp->valid < (bits)) fp->bitbuf = (fp->bitbuf<<8) | (DWORD)fgetc(fp->m_pFile), fp->valid += 8; \
  code = (fp->bitbuf >> (fp->valid-(bits))) & (mask); \
}
#define skip_bits(bits)  (fp->valid -= (bits))
#define clear_bitbuf() (fp->valid = 0, fp->bitbuf = 0)

static bool read_tree(PFILE* fp)
{
	int len;
	int base;
	int n;

	fp->orig_len = 0;
	for( n=1; n<=4; n++ )
		fp->orig_len = (fp->orig_len << 8) | (DWORD)fgetc(fp->m_pFile);

	fp->max_len = fgetc(fp->m_pFile);
	if (fp->max_len > MAX_BITLEN)
		return false;

    n = 0;
	for( len=1; len<=fp->max_len; len++ )
	{
		fp->leaves[len] = fgetc(fp->m_pFile);
		n += fp->leaves[len];
	}
    if( n>LITERALS )
		return false;

	fp->leaves[fp->max_len]++;

	base = 0;
	for( len=1; len<=fp->max_len; len++ )
	{
		fp->lit_base[len] = base;
		for( n=fp->leaves[len]; n>0; n-- )
			fp->literal[base++] = fgetc(fp->m_pFile);
    }
	fp->leaves[fp->max_len]++;
	return true;
}

static void build_tree(PFILE* fp)
{
	int nodes = 0;
	int len;
	BYTE *prefixp;

	for( len=fp->max_len; len>=1; len-- )
	{
		nodes >>= 1;
		fp->parents[len] = nodes;

		fp->lit_base[len] -= nodes;

		nodes += fp->leaves[len];
	}

	fp->peek_bits = MIN(fp->max_len, MAX_PEEK);
	prefixp = &fp->prefix_len[1<<fp->peek_bits];
	for( len=1; len<=fp->peek_bits; len++ )
	{
		int prefixes = fp->leaves[len] << (fp->peek_bits-len);
		while (prefixes--) *--prefixp = (BYTE)len;
	}
	while (prefixp > fp->prefix_len) *--prefixp = 0;
}

PFILE* P_open(const char* name,const char* mode)
{
	PFILE* fp = new PFILE;
	fp->m_pFile = fopen(name,"rb");
	if( fp->m_pFile==NULL ){delete fp;return NULL;}

	BYTE a=fgetc(fp->m_pFile);
	BYTE b=fgetc(fp->m_pFile);
	if( a!=0x1f || b!=0x1e )
	{
		P_close(fp);
		return NULL;
	}

    if( !read_tree(fp) ){delete fp;return NULL;}
	build_tree(fp);
    clear_bitbuf();

	fp->peek_mask = (1<<fp->peek_bits)-1;
	fp->eob = fp->leaves[fp->max_len]-1;
	fp->m_eof=false;

	return fp;
}

int P_close(PFILE* fp)
{
	if( fp==NULL || fp->m_pFile==NULL )
		return EOF;
	fclose( fp->m_pFile );
	delete fp;
	return 0;
}

static bool P_readonce(PFILE* fp);

int P_read( void *buf,int size,PFILE* fp )
{
	int nread = 0;
	while( size>0 )
	{
		int in_avail;
		in_avail = fp->m_strstream.Len();
		if( in_avail==0 )
		{
			if( !P_readonce(fp) )
				break;
		}
		in_avail = fp->m_strstream.Len();
		int n = in_avail>size?size:in_avail;
		fp->m_strstream.Get( buf,n );
		nread += n;
		size -= n;
		buf = (void*)( (char*)buf+n );
	}
	return nread;
}

static bool P_readonce(PFILE* fp)
{
	if( fp->m_eof )
		return false;

	int count=30000;
	while( count-- )
	{
		int len;
		register unsigned peek;

		look_bits(peek, fp->peek_bits, fp->peek_mask);
		len = fp->prefix_len[peek];
		if( len>0 )
			peek >>= fp->peek_bits - len;
		else
		{
			DWORD mask = fp->peek_mask;
			len = fp->peek_bits;
			do
			{
				len++, mask = (mask<<1)+1;
				look_bits(peek, len, mask);
		    }while( peek<(unsigned)fp->parents[len] );
		}
		if( peek==fp->eob && len==fp->max_len )
		{	fp->m_eof=true;	break;	}
		fp->m_strstream.Putc( fp->literal[peek+fp->lit_base[len]] );
		skip_bits(len);
	}
	return true;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -