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

📄 lzo1b_d.ch

📁 lzo-1.08-src.zip 高效的压缩解压代码
💻 CH
字号:
/* lzo1b_d.ch -- implementation of the LZO1B decompression algorithm   This file is part of the LZO real-time data compression library.   Copyright (C) 1996-2002 Markus Franz Xaver Johannes Oberhumer   All Rights Reserved.   The LZO library is free software; you can redistribute it and/or   modify it under the terms of the GNU General Public License as   published by the Free Software Foundation; either version 2 of   the License, or (at your option) any later version.   The LZO library is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.   You should have received a copy of the GNU General Public License   along with the LZO library; see the file COPYING.   If not, write to the Free Software Foundation, Inc.,   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.   Markus F.X.J. Oberhumer   <markus@oberhumer.com> */#include "lzo1_d.ch"#if defined(HAVE_ANY_IP) && defined(HAVE_ANY_OP)   /* too many local variables, cannot allocate registers */#  undef LZO_OPTIMIZE_GNUC_i386#endif/***********************************************************************// decompress a block of data.************************************************************************/LZO_PUBLIC(int)DO_DECOMPRESS    ( const lzo_byte *in , lzo_uint  in_len,						 lzo_byte *out, lzo_uintp out_len,                         lzo_voidp wrkmem ){#if defined(LZO_OPTIMIZE_GNUC_i386)	register lzo_byte *op __asm__("%edi");	register const lzo_byte *ip __asm__("%esi");	register lzo_uint t __asm__("%ecx");	register const lzo_byte *m_pos __asm__("%ebx");#else	register lzo_byte *op;	register const lzo_byte *ip;	register lzo_uint t;	register const lzo_byte *m_pos;#endif	const lzo_byte * const ip_end = in + in_len;#if defined(HAVE_ANY_OP)	lzo_byte * const op_end = out + *out_len;#endif	LZO_UNUSED(wrkmem);#if defined(__LZO_QUERY_DECOMPRESS)	if (__LZO_IS_DECOMPRESS_QUERY(in,in_len,out,out_len,wrkmem))		return __LZO_QUERY_DECOMPRESS(in,in_len,out,out_len,wrkmem,0,0);#endif	op = out;	ip = in;	while (TEST_IP && TEST_OP)	{		t = *ip++;		/* get marker */		if (t < R0MIN)		/* a literal run */		{			if (t == 0)				/* a R0 literal run */			{				NEED_IP(1);				t = *ip++;				if (t >= R0FAST - R0MIN)			/* a long R0 run */				{					t -= R0FAST - R0MIN;					if (t == 0)						t = R0FAST;					else					{#if 0						t = 256u << ((unsigned) t);#else						/* help the optimizer */						lzo_uint tt = 256;						do tt <<= 1; while (--t > 0);						t = tt;#endif					}					NEED_IP(t); NEED_OP(t);#if 1 && defined(LZO_UNALIGNED_OK_4)					do {						* (lzo_uint32p) (op+0) = * (const lzo_uint32p) (ip+0);						* (lzo_uint32p) (op+4) = * (const lzo_uint32p) (ip+4);						op += 8; ip += 8;						t -= 8;					} while (t > 0);#else					MEMCPY8_DS(op,ip,t);#endif					continue;				}				t += R0MIN;							/* a short R0 run */			}			NEED_IP(t); NEED_OP(t);			/* copy literal run */#if 1 && defined(LZO_UNALIGNED_OK_4)			if (t >= 4)			{				do {					* (lzo_uint32p) op = * (const lzo_uint32p) ip;					op += 4; ip += 4; t -= 4;				} while (t >= 4);				if (t > 0) do *op++ = *ip++; while (--t > 0);			}			else#endif			{#if (M3O_BITS < 7)literal1:#endif				do *op++ = *ip++; while (--t > 0);			}#if (M3O_BITS == 7)literal2:#endif			/* after a literal a match must follow */			while (TEST_IP && TEST_OP)			{				t = *ip++;			/* get R1 marker */				if (t >= R0MIN)					goto match;				NEED_IP(2); NEED_OP(M2_MIN_LEN + 1);			/* R1 match - a M2_MIN_LEN match + 1 byte literal */				assert((t & M2O_MASK) == t);				m_pos = op - M2_MIN_OFFSET;				m_pos -= t | (((lzo_uint) *ip++) << M2O_BITS);				assert(m_pos >= out); assert(m_pos < op);				TEST_LOOKBEHIND(m_pos,out);				COPY_M2;				*op++ = *ip++;			}#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP)			break;#endif		}match:		if (t >= M2_MARKER)				/* a M2 match */		{			/* get match offset */			NEED_IP(1);			m_pos = op - M2_MIN_OFFSET;			m_pos -= (t & M2O_MASK) | (((lzo_uint) *ip++) << M2O_BITS);			assert(m_pos >= out); assert(m_pos < op);			TEST_LOOKBEHIND(m_pos,out);			/* get match len */			t = (t >> M2O_BITS) - 1;			NEED_OP(t + M2_MIN_LEN - 1);			COPY_M2X;			MEMMOVE_DS(op,m_pos,t);		}		else							/* a M3 or M4 match */		{			/* get match len */			t &= M3L_MASK;			if (t == 0)			/* a M4 match */			{				NEED_IP(1);				while (*ip == 0)				{					t += 255;					ip++;					NEED_IP(1);				}				t += (M4_MIN_LEN - M3_MIN_LEN) + *ip++;			}			/* get match offset */			NEED_IP(2);			m_pos = op - (M3_MIN_OFFSET - M3_EOF_OFFSET);			m_pos -= *ip++ & M3O_MASK;			m_pos -= (lzo_uint)(*ip++) << M3O_BITS;#if defined(LZO_EOF_CODE)			if (m_pos == op)				goto eof_found;#endif			/* copy match */			assert(m_pos >= out); assert(m_pos < op);			TEST_LOOKBEHIND(m_pos,out); NEED_OP(t + M3_MIN_LEN - 1);#if defined(LZO_UNALIGNED_OK_4)			if (t >= 2 * 4 - (M3_MIN_LEN - 1) && (op - m_pos) >= 4)			{				* (lzo_uint32p) op = * (const lzo_uint32p) m_pos;				op += 4; m_pos += 4; t -= 4 - (M3_MIN_LEN - 1);				do {					* (lzo_uint32p) op = * (const lzo_uint32p) m_pos;					op += 4; m_pos += 4; t -= 4;				} while (t >= 4);				if (t > 0) do *op++ = *m_pos++; while (--t > 0);			}			else#endif			{			COPY_M3X;			MEMMOVE_DS(op,m_pos,t);			}#if (M3O_BITS < 7)			t = ip[-2] >> M3O_BITS;			if (t)			{				NEED_IP(t); NEED_OP(t);				goto literal1;			}#elif (M3O_BITS == 7)			/* optimized version */			if (ip[-2] & (1 << M3O_BITS))			{				NEED_IP(1); NEED_OP(1);				*op++ = *ip++;				goto literal2;			}#endif		}	}#if defined(LZO_EOF_CODE)#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP)	/* no EOF code was found */	*out_len = op - out;	return LZO_E_EOF_NOT_FOUND;#endifeof_found:	assert(t == 1);#endif	*out_len = op - out;	return (ip == ip_end ? LZO_E_OK :	       (ip < ip_end  ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));#if defined(HAVE_NEED_IP)input_overrun:	*out_len = op - out;	return LZO_E_INPUT_OVERRUN;#endif#if defined(HAVE_NEED_OP)output_overrun:	*out_len = op - out;	return LZO_E_OUTPUT_OVERRUN;#endif#if defined(LZO_TEST_DECOMPRESS_OVERRUN_LOOKBEHIND)lookbehind_overrun:	*out_len = op - out;	return LZO_E_LOOKBEHIND_OVERRUN;#endif}/*vi:ts=4:et*/

⌨️ 快捷键说明

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