コード例 #1
0
int LWZState::ReadByte( RageFile &f )
{
	if( fresh )
	{
		fresh = false;
		do {
			firstcode = oldcode = m_Code.Get( f, code_size );
		} while ( firstcode == clear_code );
		return firstcode;
	}

	if( sp > stack )
		return *--sp;

	int code;
	while( (code = m_Code.Get(f, code_size)) >= 0 )
	{
		if( code == clear_code )
		{
			memset( table, 0, sizeof(table) );
			for( int i = 0; i < clear_code; ++i )
				table[1][i] = i;
			code_size = set_code_size + 1;
			max_code_size = 2 * clear_code;
			max_code = clear_code + 2;
			sp = stack;
			firstcode = oldcode = m_Code.Get( f, code_size );
			return firstcode;
		}
		else if( code == end_code )
		{
			int count;
			unsigned char buf[260];

			if( m_Code.done )
				return -2;

			while( (count = GetDataBlock(f, buf)) > 0 )
				;

			if( count != 0 )
			{
				/*
				 * pm_message("missing EOD in data stream (common occurence)");
				 */
			}
			return -2;
		}
		int incode = code;

		if( code >= max_code )
		{
			*sp++ = firstcode;
			code = oldcode;
		}
		while( code >= clear_code )
		{
			*sp++ = table[1][code];
//			if (code == table[0][code])
//				RWSetMsg("circular table entry BIG ERROR");
			code = table[0][code];
		}

		*sp++ = firstcode = table[1][code];

		if( (code = max_code) < (1 << MAX_LWZ_BITS) )
		{
			table[0][code] = oldcode;
			table[1][code] = firstcode;
			++max_code;
			if (max_code >= max_code_size &&
				max_code_size < (1 << MAX_LWZ_BITS))
			{
				max_code_size *= 2;
				++code_size;
			}
		}
		oldcode = incode;

		if( sp > stack )
			return *--sp;
	}
	return code;
}