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

📄 lzhdecoder2.cpp

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

#include "stdafx.h"
#include "LzhDecoder2.h"

void CLzhDecoder2::Unstore()
{
#define UNS_BUFSIZE (16384)
//#define UNS_BUFSIZE 32768
	int how_much;
	char buf[UNS_BUFSIZE];
/**/
	if( cmpsize==-1 )
	{
		while( (how_much=fread(buf,1,UNS_BUFSIZE,in))!=0 )
		{
			if( how_much==-1 )
//			if( how_much==0 )
				break;
			fwrite(buf,1,how_much,out);
			if(feof(in)!=0) break;
			if(0!=ferror(in) || 0!=ferror(out)) break;
		}
		return;
	}
/**/
	while( cmpsize>0 )
	{
		how_much = cmpsize>UNS_BUFSIZE?UNS_BUFSIZE:cmpsize;
		if( 0>=(how_much=fread( buf,1,how_much,in )) )
			break;
		fwrite( buf,1,how_much,out );
		if(feof(in)!=0) break;
		if(0!=ferror(in) || 0!=ferror(out)) break;
		cmpsize -= how_much;
	}

}

void CLzhDecoder2::Decode( lzh_method mhd,FILE* infile,DWORD insize,
										FILE* outfile,DWORD outsize )
{
	in      = infile;
	cmpsize = insize;
	out     = outfile;
	orisize = outsize;

	DWORD dicsiz,dicbit;

	// 儊僜僢僪偵傛偭偰偄傠偄傠愗傝懼偊
	switch( mhd )
	{
	case LH0:
	case LZ4:Unstore();	return;
	default:			return;

	case ARJ:	np=17,pbit=5,dicsiz=26624;break;
	case LH4:	np=14,pbit=4,dicbit=12,dicsiz=(1<<dicbit);break;
	case LH5:	np=14,pbit=4,dicbit=13,dicsiz=(1<<dicbit);break;
	case LH6:	np=16,pbit=5,dicbit=15,dicsiz=(1<<dicbit);break;
	case LH7:	np=17,pbit=5,dicbit=16,dicsiz=(1<<dicbit);break;

	case LZ5:	dicbit=12,dicsiz=(1<<dicbit);break;
	case LZS:	dicbit=11,dicsiz=(1<<dicbit);break;

	case LH1:	np=(1<<6),dicbit=12,dicsiz=(1<<dicbit);break;
	case LH2:	dicbit=13,dicsiz=(1<<dicbit);break;
	case LH3:	np=(1<<9),dicbit=13,dicsiz=(1<<dicbit);break;
	}

	BYTE* text = new BYTE[dicsiz];
	memset( text,' ',dicsiz );

	if( LH4<=mhd && mhd<=ARJ )
	{
		init_getbits();
		blocksize = 0;
	}
	else if( mhd==LZS )
		init_getbits();
	else if( mhd==LZ5 )
	{
		flagcnt = 0;
		int i;
		for( i=0; i<256; i++ )	memset(&text[i * 13 + 18], i, 13);
		for( i=0; i<256; i++ )	text[256 * 13 + 18 + i] = i;
		for( i=0; i<256; i++ )	text[256 * 13 + 256 + 18 + i] = 255 - i;
		memset(&text[256 * 13 + 512 + 18], 0, 128);
		memset(&text[256 * 13 + 512 + 128 + 18], ' ', 128 - 18);
	}
	else if( mhd==LH3 )
		init_getbits();
	else if( mhd==LH2 )
	{
		n_max = 286;
		init_getbits();

		int             i, j, f;
		n1 = (n_max >= 256 + MAXMATCH - THRESHOLD + 1) ? 512 : n_max - 1;
		for (i = 0; i < TREESIZE_C; i++) {
			stock[i] = i;
			block[i] = 0;
		}
		for (i = 0, j = (int)n_max * 2 - 2; i < (int)n_max; i++, j--)
		{
			freq[j] = 1;
			child[j] = ~i;
			s_node[i] = j;
			block[j] = 1;
		}
		avail = 2;
		edge[1] = (short)(n_max - 1);
		i = n_max * 2 - 2;
		while (j >= 0) {
			f = freq[j] = freq[i] + freq[i - 1];
			child[j] = i;
			parent[i] = parent[i - 1] = j;
			if (f == freq[j + 1]) {
				edge[block[j] = block[j + 1]] = j;
			}
			else {
				edge[block[j] = stock[avail++]] = j;
			}
			i -= 2;
			j--;
		}

		freq[ROOT_P] = 1;
		child[ROOT_P] = ~(N_CHAR);
		s_node[N_CHAR] = ROOT_P;
		edge[block[ROOT_P] = stock[avail++]] = ROOT_P;
		most_p = ROOT_P;
		total_p = 0;
		nn = 1 << dicbit;
		nextcount = 64;
	}
	else if( mhd==LH1 )
	{
		n_max = 314;
		init_getbits();
		np = 1 << 6;

		int             i, j, f;
		n1 = (n_max >= 256 + 60 - THRESHOLD + 1) ? 512 : n_max - 1;
		for (i = 0; i < TREESIZE_C; i++)
		{
			stock[i] = i;
			block[i] = 0;
		}
		for (i = 0, j = (int)n_max * 2 - 2; i < (int)n_max; i++, j--)
		{
			freq[j] = 1;
			child[j] = ~i;
			s_node[i] = j;
			block[j] = 1;
		}
		avail = 2;
		edge[1] = (short)(n_max - 1);
		i = n_max * 2 - 2;
		while (j >= 0) {
			f = freq[j] = freq[i] + freq[i - 1];
			child[j] = i;
			parent[i] = parent[i - 1] = j;
			if (f == freq[j + 1]) {
				edge[block[j] = block[j + 1]] = j;
			}
			else {
				edge[block[j] = stock[avail++]] = j;
			}
			i -= 2;
			j--;
		}

		ready_made(0);
		make_table(np, pt_len, 8, pt_table);
	}

	// 僨僐乕僪
	DWORD count=0;
	loc=0;
	int offset=(mhd==LZS)?(0x0100-2):(0x0100-3);
	while( count<orisize )
	{
		int c = Decode_C(mhd);

		if( c<=255 )
		{
			text[loc++] = c;
			if( loc==dicsiz )
			{
				fwrite(text,1,dicsiz,out);
				loc = 0;
			}
			count++;
		}
		else
		{
			int j = c - offset;
			count += j;
			int i = Decode_P(mhd);
			if( (i=loc-i-1)<0 )
				i += dicsiz;

			for( int k=0; k<j; k++ )
			{
				text[loc++] = text[i];
				if( loc>=dicsiz )
				{
					fwrite( text,1,dicsiz,out );
					loc = 0;
				}
				if( ++i>=(int)dicsiz )
					i = 0;
			}
		}
	}

	if( loc!=0 )
		fwrite( text,1,loc,out );

	delete [] text;
}

/**************** LH4-7,ARJ,ZOO ************************/

void CLzhDecoder2::make_table(WORD nchar,BYTE* bitlen,
								WORD tablebits,WORD* table)
{
	WORD count[17],weight[17],start[17],total,*p;
	unsigned int i;
	int j,k,l,m,n,avail;

	avail = nchar;

	for( i=1; i<=16; i++ )
	{
		count[i] = 0;
		weight[i] = 1 << (16 - i);
	}

	for( i=0; i<nchar; i++ )
		count[bitlen[i]]++;

	total = 0;
	for( i=1; i<=16; i++ )
	{
		start[i] = total;
		total += weight[i] * count[i];
	}
	if( (total & 0xffff) != 0 )
		return;//error("Bad table (5)\n");

	m = 16 - tablebits;
	for( i=1; i<=tablebits; i++ )
	{
		start[i] >>= m;
		weight[i] >>= m;
	}

	j = start[tablebits + 1] >> m;
	k = 1 << tablebits;
	if( j!=0 )
		for( i=j; i<(unsigned)k; i++ )
			table[i] = 0;

	for( j=0; j<nchar; j++ )
	{
		k = bitlen[j];
		if( k==0 )
			continue;
		l = start[k] + weight[k];
		if( k<=tablebits )
		{
			for( i=start[k]; i<(unsigned)l; i++ )
				table[i] = j;
		}
		else
		{
			p = &table[(i = start[k]) >> m];
			i <<= tablebits;
			n = k - tablebits;
			while (--n >= 0)
			{
				if (*p == 0)
				{
					right[avail] = left[avail] = 0;
					*p = avail++;
				}
				if (i & 0x8000)
					p = &right[*p];
				else
					p = &left[*p];
				i <<= 1;
			}
			*p = j;
		}
		start[k] = l;
	}
}

void CLzhDecoder2::read_pt_len(short nn,short nbit,short i_special)
{
	short i, c, n=getbits((BYTE)nbit);

	if( n==0 )
	{
		c = getbits((BYTE)nbit);
		for( i=0; i<nn; i++ )	pt_len[i] = 0;
		for( i=0; i<256; i++ )	pt_table[i] = c;
	}
	else
	{
		short i = 0;
		while( i<n )
		{
			c = bitbuf >> (16-3);
			if( c==7 )
			{
				WORD mask = 1<<(16-4);
				while( mask&bitbuf )
				{
					mask >>= 1;
					c++;
				}
			}
			fillbuf( (c<7) ? 3 : c-3 );
			pt_len[i++] = (BYTE)c;
			if( i==i_special )
			{
				c = getbits(2);
				while( --c>=0 )
					pt_len[i++] = 0;
			}
		}
		while( i<nn )
			pt_len[i++] = 0;
		make_table(nn,pt_len,8,pt_table);
	}
}

void CLzhDecoder2::read_c_len()
{
	short i, c, n=getbits(CBIT);

	if( n==0 )
	{
		c = getbits(CBIT);
		for( i=0; i<NC; i++ )	c_len[i] = 0;
		for( i=0; i<4096; i++ )	c_table[i] = c;
	}
	else
	{
		short i = 0;
		while( i<n )
		{
			c = pt_table[ bitbuf>>(16-8) ];
			if( c>=NT )
			{
				WORD mask = 1<<(16-9);
				do
				{
					if( bitbuf&mask )c = right[c];
					else			 c = left[c];
					mask >>= 1;
				}while( c>=NT );
			}
			fillbuf(pt_len[c]);
			if( c<=2 )
			{
				if( c==0 )		c = 1;
				else if( c==1 )	c = getbits(4) + 3;
				else			c = getbits(CBIT) + 20;
				while( --c>=0 )
					c_len[i++] = 0;
			}
			else
				c_len[i++] = c-2;
		}
		while( i<NC )
			c_len[i++]=0;
		make_table(NC,c_len,12,c_table);
	}
}

WORD CLzhDecoder2::decode_c_st1()
{
	WORD j,mask;

	if( blocksize==0 )
	{
		blocksize = getbits(16);
		read_pt_len(NT,TBIT,3);
		read_c_len();
		read_pt_len(np,pbit,-1);
	}
	blocksize--;
	j = c_table[ bitbuf>>4 ];
	if( j<NC )
		fillbuf(c_len[j]);
	else
	{
		fillbuf(12);
		mask = 1 << (16-1);
		do
		{
			if( bitbuf&mask )	j = right[j];
			else				j = left[j];
			mask >>= 1;
		}while( j>=NC );
		fillbuf( c_len[j]-12 );
	}
	return j;
}

WORD CLzhDecoder2::decode_p_st1()
{
	WORD j, mask;

	j = pt_table[ bitbuf>>(16-8) ];
	if( j<np )
		fillbuf(pt_len[j]);
	else

⌨️ 快捷键说明

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